familia 2.0.0.pre15 → 2.0.0.pre17

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.
Files changed (288) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/.github/workflows/code-quality.yml +138 -0
  4. data/.github/workflows/code-smells.yml +85 -0
  5. data/.github/workflows/docs.yml +31 -8
  6. data/.gitignore +3 -1
  7. data/.pre-commit-config.yaml +7 -1
  8. data/.reek.yml +98 -0
  9. data/.rubocop.yml +54 -10
  10. data/.talismanrc +9 -0
  11. data/.yardopts +18 -13
  12. data/CHANGELOG.rst +86 -4
  13. data/CLAUDE.md +39 -1
  14. data/Gemfile +6 -5
  15. data/Gemfile.lock +99 -23
  16. data/LICENSE.txt +1 -1
  17. data/README.md +285 -85
  18. data/changelog.d/README.md +2 -2
  19. data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
  20. data/docs/archive/FAMILIA_TECHNICAL.md +42 -42
  21. data/docs/archive/FAMILIA_UPDATE.md +3 -3
  22. data/docs/archive/README.md +3 -2
  23. data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
  24. data/docs/conf.py +29 -0
  25. data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
  26. data/docs/guides/feature-encrypted-fields.md +785 -0
  27. data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
  28. data/docs/guides/feature-external-identifiers.md +637 -0
  29. data/docs/guides/feature-object-identifiers.md +435 -0
  30. data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
  31. data/docs/guides/feature-relationships-methods.md +684 -0
  32. data/docs/guides/feature-relationships.md +200 -0
  33. data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
  34. data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
  35. data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
  36. data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
  37. data/docs/guides/index.md +176 -0
  38. data/docs/guides/{Security-Model.md → security-model.md} +1 -1
  39. data/docs/migrating/v2.0.0-pre.md +1 -1
  40. data/docs/migrating/v2.0.0-pre11.md +2 -2
  41. data/docs/migrating/v2.0.0-pre12.md +2 -2
  42. data/docs/migrating/v2.0.0-pre5.md +33 -12
  43. data/docs/migrating/v2.0.0-pre6.md +2 -2
  44. data/docs/migrating/v2.0.0-pre7.md +8 -8
  45. data/docs/overview.md +624 -20
  46. data/docs/reference/api-technical.md +1365 -0
  47. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
  48. data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
  49. data/examples/autoloader/mega_customer.rb +3 -1
  50. data/examples/encrypted_fields.rb +378 -0
  51. data/examples/json_usage_patterns.rb +144 -0
  52. data/examples/relationships.rb +13 -13
  53. data/examples/safe_dump.rb +7 -7
  54. data/examples/single_connection_transaction_confusions.rb +379 -0
  55. data/lib/familia/base.rb +51 -10
  56. data/lib/familia/connection/handlers.rb +223 -0
  57. data/lib/familia/connection/individual_command_proxy.rb +64 -0
  58. data/lib/familia/connection/middleware.rb +75 -0
  59. data/lib/familia/connection/operation_core.rb +93 -0
  60. data/lib/familia/connection/operations.rb +277 -0
  61. data/lib/familia/connection/pipeline_core.rb +87 -0
  62. data/lib/familia/connection/transaction_core.rb +100 -0
  63. data/lib/familia/connection.rb +60 -186
  64. data/lib/familia/data_type/class_methods.rb +63 -0
  65. data/lib/familia/data_type/commands.rb +53 -51
  66. data/lib/familia/data_type/connection.rb +83 -0
  67. data/lib/familia/data_type/serialization.rb +108 -107
  68. data/lib/familia/data_type/settings.rb +96 -0
  69. data/lib/familia/data_type/types/counter.rb +1 -1
  70. data/lib/familia/data_type/types/hashkey.rb +15 -11
  71. data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
  72. data/lib/familia/data_type/types/lock.rb +3 -2
  73. data/lib/familia/data_type/types/sorted_set.rb +128 -14
  74. data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -9
  75. data/lib/familia/data_type/types/unsorted_set.rb +20 -27
  76. data/lib/familia/data_type.rb +12 -171
  77. data/lib/familia/distinguisher.rb +85 -0
  78. data/lib/familia/encryption/encrypted_data.rb +15 -24
  79. data/lib/familia/encryption/manager.rb +6 -4
  80. data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
  81. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
  82. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
  83. data/lib/familia/encryption/request_cache.rb +7 -7
  84. data/lib/familia/encryption.rb +2 -3
  85. data/lib/familia/errors.rb +9 -3
  86. data/lib/familia/features/autoloader.rb +30 -12
  87. data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
  88. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
  89. data/lib/familia/features/encrypted_fields.rb +71 -66
  90. data/lib/familia/features/expiration/extensions.rb +1 -1
  91. data/lib/familia/features/expiration.rb +31 -26
  92. data/lib/familia/features/external_identifier.rb +57 -19
  93. data/lib/familia/features/object_identifier.rb +134 -25
  94. data/lib/familia/features/quantization.rb +16 -21
  95. data/lib/familia/features/relationships/README.md +97 -0
  96. data/lib/familia/features/relationships/collection_operations.rb +104 -0
  97. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
  98. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +306 -0
  99. data/lib/familia/features/relationships/indexing.rb +182 -256
  100. data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
  101. data/lib/familia/features/relationships/participation/participant_methods.rb +164 -0
  102. data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
  103. data/lib/familia/features/relationships/participation.rb +656 -0
  104. data/lib/familia/features/relationships/participation_relationship.rb +31 -0
  105. data/lib/familia/features/relationships/score_encoding.rb +20 -20
  106. data/lib/familia/features/relationships.rb +65 -266
  107. data/lib/familia/features/safe_dump.rb +127 -130
  108. data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
  109. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
  110. data/lib/familia/features/transient_fields.rb +10 -7
  111. data/lib/familia/features.rb +10 -14
  112. data/lib/familia/field_type.rb +6 -4
  113. data/lib/familia/horreum/connection.rb +297 -0
  114. data/lib/familia/horreum/{core/database_commands.rb → database_commands.rb} +27 -17
  115. data/lib/familia/horreum/{subclass/definition.rb → definition.rb} +139 -74
  116. data/lib/familia/horreum/{subclass/management.rb → management.rb} +73 -27
  117. data/lib/familia/horreum/{core/serialization.rb → persistence.rb} +108 -185
  118. data/lib/familia/horreum/{subclass/related_fields_management.rb → related_fields.rb} +104 -23
  119. data/lib/familia/horreum/serialization.rb +172 -0
  120. data/lib/familia/horreum/{shared/settings.rb → settings.rb} +2 -1
  121. data/lib/familia/horreum/{core/utils.rb → utils.rb} +2 -1
  122. data/lib/familia/horreum.rb +222 -119
  123. data/lib/familia/json_serializer.rb +0 -1
  124. data/lib/familia/logging.rb +11 -114
  125. data/lib/familia/refinements/dear_json.rb +122 -0
  126. data/lib/familia/refinements/logger_trace.rb +20 -17
  127. data/lib/familia/refinements/stylize_words.rb +65 -0
  128. data/lib/familia/refinements/time_literals.rb +60 -52
  129. data/lib/familia/refinements.rb +2 -1
  130. data/lib/familia/secure_identifier.rb +60 -28
  131. data/lib/familia/settings.rb +83 -7
  132. data/lib/familia/utils.rb +5 -87
  133. data/lib/familia/verifiable_identifier.rb +4 -4
  134. data/lib/familia/version.rb +1 -1
  135. data/lib/familia.rb +72 -14
  136. data/lib/middleware/database_middleware.rb +56 -14
  137. data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
  138. data/try/configuration/scenarios_try.rb +2 -2
  139. data/try/connection/fiber_context_preservation_try.rb +250 -0
  140. data/try/connection/handler_constraints_try.rb +59 -0
  141. data/try/connection/operation_mode_guards_try.rb +208 -0
  142. data/try/connection/pipeline_fallback_integration_try.rb +128 -0
  143. data/try/connection/responsibility_chain_tracking_try.rb +72 -0
  144. data/try/connection/transaction_fallback_integration_try.rb +288 -0
  145. data/try/connection/transaction_mode_permissive_try.rb +153 -0
  146. data/try/connection/transaction_mode_strict_try.rb +98 -0
  147. data/try/connection/transaction_mode_warn_try.rb +131 -0
  148. data/try/connection/transaction_modes_try.rb +249 -0
  149. data/try/core/autoloader_try.rb +120 -2
  150. data/try/core/connection_try.rb +10 -10
  151. data/try/core/conventional_inheritance_try.rb +130 -0
  152. data/try/core/create_method_try.rb +15 -23
  153. data/try/core/database_consistency_try.rb +11 -10
  154. data/try/core/errors_try.rb +11 -14
  155. data/try/core/familia_extended_try.rb +2 -2
  156. data/try/core/familia_members_methods_try.rb +76 -0
  157. data/try/core/familia_try.rb +1 -1
  158. data/try/core/isolated_dbclient_try.rb +165 -0
  159. data/try/core/middleware_try.rb +16 -16
  160. data/try/core/persistence_operations_try.rb +4 -4
  161. data/try/core/pools_try.rb +42 -26
  162. data/try/core/secure_identifier_try.rb +28 -24
  163. data/try/core/time_utils_try.rb +10 -10
  164. data/try/core/tools_try.rb +3 -3
  165. data/try/core/utils_try.rb +2 -2
  166. data/try/data_types/boolean_try.rb +4 -4
  167. data/try/data_types/datatype_base_try.rb +0 -2
  168. data/try/data_types/list_try.rb +10 -10
  169. data/try/data_types/sorted_set_try.rb +5 -5
  170. data/try/data_types/sorted_set_zadd_options_try.rb +625 -0
  171. data/try/data_types/string_try.rb +12 -12
  172. data/try/data_types/unsortedset_try.rb +33 -0
  173. data/try/debugging/cache_behavior_tracer.rb +7 -7
  174. data/try/debugging/debug_aad_process.rb +1 -1
  175. data/try/debugging/debug_concealed_internal.rb +1 -1
  176. data/try/debugging/debug_cross_context.rb +1 -1
  177. data/try/debugging/debug_fresh_cross_context.rb +1 -1
  178. data/try/debugging/encryption_method_tracer.rb +10 -10
  179. data/try/edge_cases/hash_symbolization_try.rb +1 -1
  180. data/try/edge_cases/ttl_side_effects_try.rb +1 -1
  181. data/try/encryption/config_persistence_try.rb +2 -2
  182. data/try/encryption/encryption_core_try.rb +19 -19
  183. data/try/encryption/instance_variable_scope_try.rb +1 -1
  184. data/try/encryption/module_loading_try.rb +2 -2
  185. data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
  186. data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
  187. data/try/encryption/secure_memory_handling_try.rb +1 -1
  188. data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
  189. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
  190. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
  191. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
  192. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
  193. data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
  194. data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
  195. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
  196. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
  197. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
  198. data/try/features/external_identifier/external_identifier_try.rb +1 -1
  199. data/try/features/feature_dependencies_try.rb +3 -3
  200. data/try/features/field_groups_try.rb +244 -0
  201. data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
  202. data/try/features/object_identifier/object_identifier_try.rb +10 -0
  203. data/try/features/quantization/quantization_try.rb +1 -1
  204. data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
  205. data/try/features/relationships/indexing_try.rb +443 -0
  206. data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
  207. data/try/features/relationships/participation_commands_verification_try.rb +105 -0
  208. data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
  209. data/try/features/relationships/participation_reverse_index_try.rb +196 -0
  210. data/try/features/relationships/relationships_api_changes_try.rb +72 -71
  211. data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
  212. data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
  213. data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
  214. data/try/features/relationships/relationships_performance_try.rb +20 -20
  215. data/try/features/relationships/relationships_try.rb +27 -38
  216. data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
  217. data/try/features/transient_fields/refresh_reset_try.rb +3 -1
  218. data/try/features/transient_fields/simple_refresh_test.rb +1 -1
  219. data/try/helpers/test_cleanup.rb +86 -0
  220. data/try/helpers/test_helpers.rb +6 -7
  221. data/try/horreum/auto_indexing_on_save_try.rb +212 -0
  222. data/try/horreum/base_try.rb +3 -2
  223. data/try/horreum/commands_try.rb +3 -1
  224. data/try/horreum/defensive_initialization_try.rb +86 -0
  225. data/try/horreum/destroy_related_fields_cleanup_try.rb +332 -0
  226. data/try/horreum/initialization_try.rb +11 -7
  227. data/try/horreum/relations_try.rb +21 -13
  228. data/try/horreum/serialization_try.rb +12 -11
  229. data/try/horreum/settings_try.rb +2 -0
  230. data/try/integration/cross_component_try.rb +3 -3
  231. data/try/memory/memory_basic_test.rb +1 -1
  232. data/try/memory/memory_docker_ruby_dump.sh +2 -2
  233. data/try/models/customer_safe_dump_try.rb +1 -1
  234. data/try/models/customer_try.rb +13 -15
  235. data/try/models/datatype_base_try.rb +3 -3
  236. data/try/models/familia_object_try.rb +9 -8
  237. data/try/performance/benchmarks_try.rb +2 -2
  238. data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
  239. data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
  240. data/try/prototypes/atomic_saves_v4.rb +1 -1
  241. data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
  242. data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  243. data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  244. data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
  245. data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
  246. data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
  247. data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
  248. data/try/prototypes/pooling/pool_siege.rb +11 -11
  249. data/try/prototypes/pooling/run_stress_tests.rb +7 -7
  250. data/try/refinements/dear_json_array_methods_try.rb +53 -0
  251. data/try/refinements/dear_json_hash_methods_try.rb +54 -0
  252. data/try/refinements/logger_trace_methods_try.rb +44 -0
  253. data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
  254. data/try/refinements/time_literals_string_methods_try.rb +80 -0
  255. data/try/valkey.conf +26 -0
  256. metadata +92 -52
  257. data/.rubocop_todo.yml +0 -208
  258. data/docs/connection_pooling.md +0 -192
  259. data/docs/guides/Connection-Pooling-Guide.md +0 -437
  260. data/docs/guides/Encrypted-Fields-Overview.md +0 -101
  261. data/docs/guides/Feature-System-Autoloading.md +0 -198
  262. data/docs/guides/Home.md +0 -116
  263. data/docs/guides/Relationships-Guide.md +0 -737
  264. data/docs/guides/relationships-methods.md +0 -266
  265. data/docs/reference/auditing_database_commands.rb +0 -228
  266. data/examples/permissions.rb +0 -240
  267. data/lib/familia/features/relationships/cascading.rb +0 -437
  268. data/lib/familia/features/relationships/membership.rb +0 -497
  269. data/lib/familia/features/relationships/permission_management.rb +0 -264
  270. data/lib/familia/features/relationships/querying.rb +0 -615
  271. data/lib/familia/features/relationships/redis_operations.rb +0 -274
  272. data/lib/familia/features/relationships/tracking.rb +0 -418
  273. data/lib/familia/horreum/core/connection.rb +0 -73
  274. data/lib/familia/horreum/core.rb +0 -21
  275. data/lib/familia/refinements/snake_case.rb +0 -40
  276. data/lib/familia/validation/command_recorder.rb +0 -336
  277. data/lib/familia/validation/expectations.rb +0 -519
  278. data/lib/familia/validation/validation_helpers.rb +0 -443
  279. data/lib/familia/validation/validator.rb +0 -412
  280. data/lib/familia/validation.rb +0 -140
  281. data/try/data_types/set_try.rb +0 -33
  282. data/try/features/relationships/categorical_permissions_try.rb +0 -515
  283. data/try/features/safe_dump/module_based_extensions_try.rb +0 -100
  284. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -107
  285. data/try/validation/atomic_operations_try.rb.disabled +0 -320
  286. data/try/validation/command_validation_try.rb.disabled +0 -207
  287. data/try/validation/performance_validation_try.rb.disabled +0 -324
  288. data/try/validation/real_world_scenarios_try.rb.disabled +0 -390
data/CHANGELOG.rst CHANGED
@@ -12,6 +12,88 @@ Versioning <https://semver.org/spec/v2.0.0.html>`__.
12
12
 
13
13
  <!--scriv-insert-here-->
14
14
 
15
+ .. _changelog-2.0.0.pre17:
16
+
17
+ 2.0.0.pre17 — 2025-10-03
18
+ ========================
19
+
20
+ Added
21
+ -----
22
+
23
+ - **SortedSet#add**: Full ZADD option support (NX, XX, GT, LT, CH) for atomic conditional operations and accurate change tracking. This enables proper index management with timestamp preservation, update-only operations, conditional score updates, and analytics tracking. Closes issue #135.
24
+
25
+ Fixed
26
+ -----
27
+
28
+ - Restored objid provenance tracking when loading objects from Redis. The ``ObjectIdentifier`` feature now infers the generator type (:uuid_v7, :uuid_v4, :hex) from the objid format, enabling dependent features like ``ExternalIdentifier`` to derive external identifiers from loaded objects. PR #131
29
+
30
+ AI Assistance
31
+ -------------
32
+
33
+ - Claude Code assisted with implementing the ``infer_objid_generator`` method and updating the setter logic in ``lib/familia/features/object_identifier.rb``.
34
+
35
+ - Claude Code assisted with Redis ZADD option semantics research, mutual exclusivity validation design, comprehensive test case matrix creation (50+ test cases), and YAML documentation examples.
36
+
37
+ .. _changelog-2.0.0.pre16:
38
+
39
+ 2.0.0.pre16 — 2025-09-30
40
+ ========================
41
+
42
+ Added
43
+ -----
44
+
45
+ - Added support for instance-scoped unique indexes via ``unique_index`` with ``within:`` parameter. Issue #128
46
+
47
+ Example: ``unique_index :badge_number, :badge_index, within: Company`` creates per-company unique badge lookups using HashKey DataType.
48
+
49
+ Changed
50
+ -------
51
+
52
+ - **BREAKING**: Consolidated relationships API by replacing ``tracked_in`` and ``member_of`` with unified ``participates_in`` method. PR #110
53
+ - **BREAKING**: Renamed ``context_class`` terminology to ``target_class`` throughout relationships module for clarity
54
+ - **BREAKING**: Removed ``tracking.rb`` and ``membership.rb`` modules, merged functionality into ``participation.rb``
55
+ - **BREAKING**: Updated method names and configuration keys to use ``target`` instead of ``context`` terminology
56
+ - Added ``bidirectional`` parameter to ``participates_in`` to control generation of convenience methods (default: true)
57
+ - Added support for different collection types (sorted_set, set, list) in unified ``participates_in`` API
58
+ - Renamed ``class_tracked_in`` to ``class_participates_in`` for consistency
59
+
60
+ - Renamed DataType classes to avoid Ruby namespace confusion: ``Familia::String`` → ``Familia::StringKey``, ``Familia::List`` → ``Familia::ListKey``
61
+ - Added dual registration for both traditional and explicit method names (``string``/``stringkey``, ``list``/``listkey``)
62
+ - Updated ``Counter`` and ``Lock`` to inherit from ``StringKey`` instead of ``String``
63
+
64
+ - **BREAKING:** Renamed indexing API methods for clarity. Issue #128
65
+
66
+ - ``class_indexed_by`` → ``unique_index`` (1:1 field-to-object mapping via HashKey)
67
+ - ``indexed_by`` → ``multi_index`` (1:many field-to-objects mapping via UnsortedSet)
68
+ - Parameter ``target:`` → ``within:`` for consistency across both index types
69
+
70
+ - **BREAKING:** Changed ``multi_index`` to use ``UnsortedSet`` instead of ``SortedSet``. Issue #128
71
+
72
+ Multi-value indexes no longer include temporal scoring. This aligns with the design philosophy that indexing is for finding objects by attribute, not ordering them. Sort results in Ruby when needed: ``employees.sort_by(&:hire_date)``
73
+
74
+ Documentation
75
+ -------------
76
+
77
+ - Updated overview documentation to explain dual naming system and namespace safety benefits
78
+ - Enhanced examples to demonstrate both traditional and explicit DataType method naming
79
+
80
+ - Updated inline module documentation
81
+ - ``Familia::Features::Relationships::Indexing`` with comprehensive examples, terminology guide, and design philosophy.
82
+ - ``Familia::Features::Relationships::Participation`` to clarify differences from indexing module.
83
+
84
+ AI Assistance
85
+ -------------
86
+
87
+ - Comprehensive analysis of existing ``tracked_in`` and ``member_of`` implementations
88
+ - Design and implementation of unified ``participates_in`` API integrating both functionalities
89
+ - Systematic refactoring of codebase terminology from context to target
90
+ - Complete test suite updates to verify API consolidation and new functionality
91
+
92
+ - DataType class renaming and dual registration system implementation designed and developed with Claude Code assistance
93
+ - All test updates and documentation enhancements created with AI support
94
+
95
+ - Architecture design, implementation, test updates, and documentation for indexing API refactoring completed with Claude Code assistance. Issue #128
96
+
15
97
  .. _changelog-2.0.0.pre14:
16
98
 
17
99
  2.0.0.pre14 — 2025-09-08
@@ -293,7 +375,7 @@ Fixed
293
375
  (e.g., ``find_by_email``) would fail to correctly instantiate objects
294
376
  from the index, returning partially-formed objects.
295
377
 
296
- - Refactored connection handling to properly cache and reuse Redis
378
+ - Refactored connection handling to properly cache and reuse Valkey/Redis
297
379
  connections. This eliminates repetitive “Overriding existing
298
380
  connection” warnings and improves performance.
299
381
 
@@ -342,9 +424,9 @@ Changed
342
424
 
343
425
  - **BREAKING**: ``tracked_in :global, collection`` syntax now raises
344
426
  ArgumentError - use ``class_tracked_in collection`` instead
345
- - **BREAKING**: ``indexed_by field, index, context: :global`` syntax
427
+ - **BREAKING**: ``indexed_by field, index, target: :global`` syntax
346
428
  replaced with ``class_indexed_by field, index``
347
- - **BREAKING**: ``indexed_by field, index, context: SomeClass`` syntax
429
+ - **BREAKING**: ``indexed_by field, index, target: SomeClass`` syntax
348
430
  replaced with ``indexed_by field, index, parent: SomeClass``
349
431
  - Relationships API now provides consistent parameter naming across all
350
432
  relationship types
@@ -498,7 +580,7 @@ Added
498
580
  ~~~~~
499
581
 
500
582
  - Complete API redesign for clarity and modern Ruby conventions
501
- - Valkey compatibility alongside traditional Redis support
583
+ - Valkey compatibility alongside traditional Valkey/Redis support
502
584
  - Ruby 3.4+ modernization with fiber and thread safety improvements
503
585
  - Connection pooling foundation with provider pattern architecture
504
586
 
data/CLAUDE.md CHANGED
@@ -75,7 +75,7 @@ Add changelog fragment with each user-facing or documented change (optional but
75
75
 
76
76
  2. **`Familia::DataType`** - Base class for Valkey data type wrappers
77
77
  - Located in `lib/familia/data_type.rb`
78
- - Provides String, List, Set, SortedSet, HashKey implementations
78
+ - Provides String, List, UnsortedSet, SortedSet, HashKey implementations
79
79
  - Each type has its own class in `lib/familia/data_type/types/`
80
80
 
81
81
  3. **`Familia::Base`** - Common module for both Horreum and DataType
@@ -92,6 +92,44 @@ Familia uses a modular feature system where features are mixed into classes:
92
92
 
93
93
  **Inheritance Chain**: `MyClass < Familia::Horreum` automatically extends `ClassMethods` and `Features`
94
94
 
95
+ **Common Pitfall: Overriding initialize**
96
+
97
+ ⚠️ **Do NOT override `initialize` without calling `super`** - this breaks related field initialization.
98
+
99
+ **Bad - will cause crashes:**
100
+ ```ruby
101
+ class User < Familia::Horreum
102
+ def initialize(email)
103
+ @email = email # Missing super! Related fields won't work
104
+ end
105
+ end
106
+ ```
107
+
108
+ **Good - use the `init` hook instead:**
109
+ ```ruby
110
+ class User < Familia::Horreum
111
+ def init(email = nil)
112
+ @email = email # Called after super, related fields work
113
+ end
114
+ end
115
+ ```
116
+
117
+ **Good - call super explicitly:**
118
+ ```ruby
119
+ class User < Familia::Horreum
120
+ def initialize(email = nil, **kwargs)
121
+ super(**kwargs) # ✓ Related fields initialized
122
+ @email = email
123
+ end
124
+ end
125
+ ```
126
+
127
+ **Why this matters**: Familia's `initialize` method calls `initialize_relatives` to set up DataType objects (lists, sets, etc.). Without calling `super`, these objects remain nil and you'll get helpful errors pointing to the missing super call.
128
+
129
+ **When to use each approach:**
130
+ - **Use `init` hook** (preferred): For simple initialization logic that doesn't need to intercept constructor arguments. The `init` method is called automatically after `super` with the same arguments passed to `new`.
131
+ - **Use explicit `super`**: When you need full control over initialization order or need to transform arguments before passing to parent. Remember to pass `**kwargs` to preserve keyword argument handling.
132
+
95
133
  **DataType Definition**: Use class methods to define keystore database-backed attributes:
96
134
  ```ruby
97
135
  class User < Familia::Horreum
data/Gemfile CHANGED
@@ -5,21 +5,22 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  group :test do
8
- gem 'tryouts', '~> 3.6.0', require: false
9
8
  gem 'concurrent-ruby', '~> 1.3.5', require: false
10
9
  gem 'ruby-prof'
11
10
  gem 'stackprof'
11
+ gem 'timecop', require: false
12
+ gem 'tryouts', '~> 3.6.0', require: false
12
13
  end
13
14
 
14
15
  group :development, :test do
15
- # byebug only works with MRI
16
- gem 'byebug', '~> 11.0', require: false if RUBY_ENGINE == 'ruby'
16
+ gem 'debug', require: false
17
17
  gem 'irb', '~> 1.15.2', require: false
18
- gem 'kramdown', require: false # Required for YARD markdown processing
19
- gem 'pry-byebug', '~> 3.10.1', require: false if RUBY_ENGINE == 'ruby'
18
+ gem 'redcarpet', require: false
19
+ gem 'reek', require: false
20
20
  gem 'rubocop', require: false
21
21
  gem 'rubocop-performance', require: false
22
22
  gem 'rubocop-thread_safety', require: false
23
+ gem 'solargraph', require: false
23
24
  gem 'yard', '~> 0.9', require: false
24
25
  end
25
26
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- familia (2.0.0.pre15)
4
+ familia (2.0.0.pre17)
5
5
  benchmark (~> 0.4)
6
6
  connection_pool (~> 2.5)
7
7
  csv (~> 3.3)
@@ -15,16 +15,47 @@ GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
17
  ast (2.4.3)
18
+ backport (1.2.0)
18
19
  base64 (0.3.0)
19
20
  benchmark (0.4.1)
20
21
  bigdecimal (3.2.3)
21
- byebug (11.1.3)
22
- coderay (1.1.3)
23
22
  concurrent-ruby (1.3.5)
24
23
  connection_pool (2.5.3)
25
24
  csv (3.3.5)
26
25
  date (3.4.1)
26
+ debug (1.11.0)
27
+ irb (~> 1.10)
28
+ reline (>= 0.3.8)
27
29
  diff-lcs (1.6.2)
30
+ dry-configurable (1.3.0)
31
+ dry-core (~> 1.1)
32
+ zeitwerk (~> 2.6)
33
+ dry-core (1.1.0)
34
+ concurrent-ruby (~> 1.0)
35
+ logger
36
+ zeitwerk (~> 2.6)
37
+ dry-inflector (1.2.0)
38
+ dry-initializer (3.2.0)
39
+ dry-logic (1.6.0)
40
+ bigdecimal
41
+ concurrent-ruby (~> 1.0)
42
+ dry-core (~> 1.1)
43
+ zeitwerk (~> 2.6)
44
+ dry-schema (1.14.1)
45
+ concurrent-ruby (~> 1.0)
46
+ dry-configurable (~> 1.0, >= 1.0.1)
47
+ dry-core (~> 1.1)
48
+ dry-initializer (~> 3.2)
49
+ dry-logic (~> 1.5)
50
+ dry-types (~> 1.8)
51
+ zeitwerk (~> 2.6)
52
+ dry-types (1.8.3)
53
+ bigdecimal (~> 3.0)
54
+ concurrent-ruby (~> 1.0)
55
+ dry-core (~> 1.0)
56
+ dry-inflector (~> 1.0)
57
+ dry-logic (~> 1.4)
58
+ zeitwerk (~> 2.6)
28
59
  erb (5.0.2)
29
60
  ffi (1.17.2)
30
61
  ffi (1.17.2-arm64-darwin)
@@ -33,20 +64,29 @@ GEM
33
64
  pp (>= 0.6.0)
34
65
  rdoc (>= 4.0.0)
35
66
  reline (>= 0.4.2)
36
- json (2.13.0)
67
+ jaro_winkler (1.6.1)
68
+ json (2.15.0)
37
69
  kramdown (2.5.1)
38
70
  rexml (>= 3.3.9)
71
+ kramdown-parser-gfm (1.1.0)
72
+ kramdown (~> 2.0)
39
73
  language_server-protocol (3.17.0.5)
40
74
  lint_roller (1.1.0)
41
75
  logger (1.7.0)
42
- method_source (1.1.0)
76
+ mini_portile2 (2.8.9)
43
77
  minitest (5.25.5)
78
+ nokogiri (1.18.10)
79
+ mini_portile2 (~> 2.8.2)
80
+ racc (~> 1.4)
81
+ nokogiri (1.18.10-arm64-darwin)
82
+ racc (~> 1.4)
83
+ observer (0.1.2)
44
84
  oj (3.16.11)
45
85
  bigdecimal (>= 3.0)
46
86
  ostruct (>= 0.2)
47
87
  ostruct (0.6.3)
48
88
  parallel (1.27.0)
49
- parser (3.3.8.0)
89
+ parser (3.3.9.0)
50
90
  ast (~> 2.4.1)
51
91
  racc
52
92
  pastel (0.8.0)
@@ -54,13 +94,7 @@ GEM
54
94
  pp (0.6.2)
55
95
  prettyprint
56
96
  prettyprint (0.2.0)
57
- prism (1.4.0)
58
- pry (0.14.2)
59
- coderay (~> 1.1)
60
- method_source (~> 1.0)
61
- pry-byebug (3.10.1)
62
- byebug (~> 11.0)
63
- pry (>= 0.13, < 0.15)
97
+ prism (1.5.1)
64
98
  psych (5.2.6)
65
99
  date
66
100
  stringio
@@ -68,16 +102,27 @@ GEM
68
102
  rainbow (3.1.1)
69
103
  rbnacl (7.1.2)
70
104
  ffi (~> 1)
105
+ rbs (3.9.5)
106
+ logger
71
107
  rdoc (6.14.2)
72
108
  erb
73
109
  psych (>= 4.0.0)
110
+ redcarpet (3.6.1)
74
111
  redis (5.4.1)
75
112
  redis-client (>= 0.22.0)
76
113
  redis-client (0.25.1)
77
114
  connection_pool
78
- regexp_parser (2.10.0)
115
+ reek (6.5.0)
116
+ dry-schema (~> 1.13)
117
+ logger (~> 1.6)
118
+ parser (~> 3.3.0)
119
+ rainbow (>= 2.0, < 4.0)
120
+ rexml (~> 3.1)
121
+ regexp_parser (2.11.3)
79
122
  reline (0.6.2)
80
123
  io-console (~> 0.5)
124
+ reverse_markdown (3.0.0)
125
+ nokogiri
81
126
  rexml (3.4.1)
82
127
  rspec (3.13.1)
83
128
  rspec-core (~> 3.13.0)
@@ -92,7 +137,7 @@ GEM
92
137
  diff-lcs (>= 1.2.0, < 2.0)
93
138
  rspec-support (~> 3.13.0)
94
139
  rspec-support (3.13.4)
95
- rubocop (1.78.0)
140
+ rubocop (1.81.1)
96
141
  json (~> 2.3)
97
142
  language_server-protocol (~> 3.17.0.2)
98
143
  lint_roller (~> 1.1.0)
@@ -100,10 +145,10 @@ GEM
100
145
  parser (>= 3.3.0.2)
101
146
  rainbow (>= 2.2.2, < 4.0)
102
147
  regexp_parser (>= 2.9.3, < 3.0)
103
- rubocop-ast (>= 1.45.1, < 2.0)
148
+ rubocop-ast (>= 1.47.1, < 2.0)
104
149
  ruby-progressbar (~> 1.7)
105
150
  unicode-display_width (>= 2.4.0, < 4.0)
106
- rubocop-ast (1.46.0)
151
+ rubocop-ast (1.47.1)
107
152
  parser (>= 3.3.7.2)
108
153
  prism (~> 1.4)
109
154
  rubocop-performance (1.25.0)
@@ -117,8 +162,32 @@ GEM
117
162
  ruby-prof (1.7.2)
118
163
  base64
119
164
  ruby-progressbar (1.13.0)
165
+ solargraph (0.57.0)
166
+ backport (~> 1.2)
167
+ benchmark (~> 0.4)
168
+ bundler (~> 2.0)
169
+ diff-lcs (~> 1.4)
170
+ jaro_winkler (~> 1.6, >= 1.6.1)
171
+ kramdown (~> 2.3)
172
+ kramdown-parser-gfm (~> 1.1)
173
+ logger (~> 1.6)
174
+ observer (~> 0.1)
175
+ ostruct (~> 0.6)
176
+ parser (~> 3.0)
177
+ prism (~> 1.4)
178
+ rbs (>= 3.6.1, <= 4.0.0.dev.4)
179
+ reverse_markdown (~> 3.0)
180
+ rubocop (~> 1.76)
181
+ thor (~> 1.0)
182
+ tilt (~> 2.0)
183
+ yard (~> 0.9, >= 0.9.24)
184
+ yard-activesupport-concern (~> 0.0)
185
+ yard-solargraph (~> 0.1)
120
186
  stackprof (0.2.27)
121
187
  stringio (3.1.7)
188
+ thor (1.4.0)
189
+ tilt (2.6.1)
190
+ timecop (0.9.10)
122
191
  tryouts (3.6.0)
123
192
  concurrent-ruby (~> 1.0)
124
193
  irb
@@ -131,29 +200,36 @@ GEM
131
200
  tty-color (0.6.0)
132
201
  tty-cursor (0.7.1)
133
202
  tty-screen (0.8.2)
134
- unicode-display_width (3.1.4)
135
- unicode-emoji (~> 4.0, >= 4.0.4)
136
- unicode-emoji (4.0.4)
203
+ unicode-display_width (3.2.0)
204
+ unicode-emoji (~> 4.1)
205
+ unicode-emoji (4.1.0)
137
206
  uri-valkey (1.4.0)
138
207
  yard (0.9.37)
208
+ yard-activesupport-concern (0.0.1)
209
+ yard (>= 0.8)
210
+ yard-solargraph (0.1.0)
211
+ yard (~> 0.9)
212
+ zeitwerk (2.7.3)
139
213
 
140
214
  PLATFORMS
141
215
  arm64-darwin-24
142
216
  ruby
143
217
 
144
218
  DEPENDENCIES
145
- byebug (~> 11.0)
146
219
  concurrent-ruby (~> 1.3.5)
220
+ debug
147
221
  familia!
148
222
  irb (~> 1.15.2)
149
- kramdown
150
- pry-byebug (~> 3.10.1)
151
223
  rbnacl (~> 7.1, >= 7.1.1)
224
+ redcarpet
225
+ reek
152
226
  rubocop
153
227
  rubocop-performance
154
228
  rubocop-thread_safety
155
229
  ruby-prof
230
+ solargraph
156
231
  stackprof
232
+ timecop
157
233
  tryouts (~> 3.6.0)
158
234
  yard (~> 0.9)
159
235
 
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2010-2024 Delano Mandelbaum
3
+ Copyright (c) 2010-ongoing delano, contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal