exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.4__py3-none-any.whl

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 (341) hide show
  1. exonware/__init__.py +2 -1
  2. exonware/conf.py +2 -2
  3. exonware/xwsystem/__init__.py +115 -43
  4. exonware/xwsystem/base.py +30 -0
  5. exonware/xwsystem/caching/__init__.py +39 -13
  6. exonware/xwsystem/caching/base.py +24 -6
  7. exonware/xwsystem/caching/bloom_cache.py +2 -2
  8. exonware/xwsystem/caching/cache_manager.py +2 -1
  9. exonware/xwsystem/caching/conditional.py +2 -2
  10. exonware/xwsystem/caching/contracts.py +85 -139
  11. exonware/xwsystem/caching/decorators.py +6 -19
  12. exonware/xwsystem/caching/defs.py +2 -1
  13. exonware/xwsystem/caching/disk_cache.py +2 -1
  14. exonware/xwsystem/caching/distributed.py +2 -1
  15. exonware/xwsystem/caching/errors.py +2 -1
  16. exonware/xwsystem/caching/events.py +110 -27
  17. exonware/xwsystem/caching/eviction_strategies.py +2 -2
  18. exonware/xwsystem/caching/external_caching_python.py +701 -0
  19. exonware/xwsystem/caching/facade.py +253 -0
  20. exonware/xwsystem/caching/factory.py +300 -0
  21. exonware/xwsystem/caching/fluent.py +14 -12
  22. exonware/xwsystem/caching/integrity.py +21 -6
  23. exonware/xwsystem/caching/lfu_cache.py +2 -1
  24. exonware/xwsystem/caching/lfu_optimized.py +18 -6
  25. exonware/xwsystem/caching/lru_cache.py +7 -4
  26. exonware/xwsystem/caching/memory_bounded.py +2 -2
  27. exonware/xwsystem/caching/metrics_exporter.py +2 -2
  28. exonware/xwsystem/caching/observable_cache.py +2 -2
  29. exonware/xwsystem/caching/pluggable_cache.py +2 -2
  30. exonware/xwsystem/caching/rate_limiter.py +2 -2
  31. exonware/xwsystem/caching/read_through.py +2 -2
  32. exonware/xwsystem/caching/secure_cache.py +81 -28
  33. exonware/xwsystem/caching/serializable.py +9 -7
  34. exonware/xwsystem/caching/stats.py +2 -2
  35. exonware/xwsystem/caching/tagging.py +2 -2
  36. exonware/xwsystem/caching/ttl_cache.py +4 -3
  37. exonware/xwsystem/caching/two_tier_cache.py +6 -3
  38. exonware/xwsystem/caching/utils.py +30 -12
  39. exonware/xwsystem/caching/validation.py +2 -2
  40. exonware/xwsystem/caching/warming.py +6 -3
  41. exonware/xwsystem/caching/write_behind.py +15 -6
  42. exonware/xwsystem/config/__init__.py +11 -17
  43. exonware/xwsystem/config/base.py +5 -5
  44. exonware/xwsystem/config/contracts.py +93 -153
  45. exonware/xwsystem/config/defaults.py +3 -2
  46. exonware/xwsystem/config/defs.py +3 -2
  47. exonware/xwsystem/config/errors.py +2 -5
  48. exonware/xwsystem/config/logging.py +12 -8
  49. exonware/xwsystem/config/logging_setup.py +3 -2
  50. exonware/xwsystem/config/performance.py +1 -46
  51. exonware/xwsystem/config/performance_modes.py +9 -8
  52. exonware/xwsystem/config/version_manager.py +1 -0
  53. exonware/xwsystem/config.py +27 -0
  54. exonware/xwsystem/console/__init__.py +53 -0
  55. exonware/xwsystem/console/base.py +133 -0
  56. exonware/xwsystem/console/cli/__init__.py +61 -0
  57. exonware/xwsystem/{cli → console/cli}/args.py +27 -24
  58. exonware/xwsystem/{cli → console/cli}/base.py +18 -87
  59. exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
  60. exonware/xwsystem/console/cli/console.py +98 -0
  61. exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
  62. exonware/xwsystem/console/cli/defs.py +87 -0
  63. exonware/xwsystem/console/cli/encoding.py +69 -0
  64. exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
  65. exonware/xwsystem/console/cli/event_logger.py +166 -0
  66. exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
  67. exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
  68. exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
  69. exonware/xwsystem/console/contracts.py +113 -0
  70. exonware/xwsystem/console/defs.py +154 -0
  71. exonware/xwsystem/console/errors.py +34 -0
  72. exonware/xwsystem/console/event_logger.py +385 -0
  73. exonware/xwsystem/console/writer.py +132 -0
  74. exonware/xwsystem/contracts.py +28 -0
  75. exonware/xwsystem/data_structures/__init__.py +23 -0
  76. exonware/xwsystem/data_structures/trie.py +34 -0
  77. exonware/xwsystem/data_structures/union_find.py +144 -0
  78. exonware/xwsystem/defs.py +17 -0
  79. exonware/xwsystem/errors.py +23 -0
  80. exonware/xwsystem/facade.py +62 -0
  81. exonware/xwsystem/http_client/__init__.py +22 -1
  82. exonware/xwsystem/http_client/advanced_client.py +8 -5
  83. exonware/xwsystem/http_client/base.py +3 -2
  84. exonware/xwsystem/http_client/client.py +7 -4
  85. exonware/xwsystem/http_client/contracts.py +42 -56
  86. exonware/xwsystem/http_client/defs.py +2 -1
  87. exonware/xwsystem/http_client/errors.py +2 -1
  88. exonware/xwsystem/http_client/facade.py +156 -0
  89. exonware/xwsystem/io/__init__.py +22 -3
  90. exonware/xwsystem/io/archive/__init__.py +8 -2
  91. exonware/xwsystem/io/archive/archive.py +1 -1
  92. exonware/xwsystem/io/archive/archive_files.py +4 -7
  93. exonware/xwsystem/io/archive/archivers.py +120 -10
  94. exonware/xwsystem/io/archive/base.py +4 -5
  95. exonware/xwsystem/io/archive/codec_integration.py +1 -2
  96. exonware/xwsystem/io/archive/compression.py +1 -2
  97. exonware/xwsystem/io/archive/facade.py +263 -0
  98. exonware/xwsystem/io/archive/formats/__init__.py +2 -3
  99. exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
  100. exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
  101. exonware/xwsystem/io/archive/formats/rar.py +11 -5
  102. exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
  103. exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
  104. exonware/xwsystem/io/archive/formats/tar.py +52 -7
  105. exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
  106. exonware/xwsystem/io/archive/formats/zip.py +1 -2
  107. exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
  108. exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
  109. exonware/xwsystem/io/base.py +119 -115
  110. exonware/xwsystem/io/codec/__init__.py +4 -2
  111. exonware/xwsystem/io/codec/base.py +19 -13
  112. exonware/xwsystem/io/codec/contracts.py +59 -2
  113. exonware/xwsystem/io/codec/registry.py +67 -21
  114. exonware/xwsystem/io/common/__init__.py +1 -1
  115. exonware/xwsystem/io/common/atomic.py +29 -16
  116. exonware/xwsystem/io/common/base.py +11 -10
  117. exonware/xwsystem/io/common/lock.py +6 -5
  118. exonware/xwsystem/io/common/path_manager.py +2 -1
  119. exonware/xwsystem/io/common/watcher.py +1 -2
  120. exonware/xwsystem/io/contracts.py +301 -433
  121. exonware/xwsystem/io/contracts_1.py +1180 -0
  122. exonware/xwsystem/io/data_operations.py +19 -20
  123. exonware/xwsystem/io/defs.py +4 -3
  124. exonware/xwsystem/io/errors.py +3 -2
  125. exonware/xwsystem/io/facade.py +87 -61
  126. exonware/xwsystem/io/file/__init__.py +1 -1
  127. exonware/xwsystem/io/file/base.py +8 -9
  128. exonware/xwsystem/io/file/conversion.py +2 -3
  129. exonware/xwsystem/io/file/file.py +61 -18
  130. exonware/xwsystem/io/file/paged_source.py +8 -8
  131. exonware/xwsystem/io/file/paging/__init__.py +1 -2
  132. exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
  133. exonware/xwsystem/io/file/paging/line_paging.py +2 -3
  134. exonware/xwsystem/io/file/paging/record_paging.py +2 -3
  135. exonware/xwsystem/io/file/paging/registry.py +1 -2
  136. exonware/xwsystem/io/file/source.py +13 -17
  137. exonware/xwsystem/io/filesystem/__init__.py +1 -1
  138. exonware/xwsystem/io/filesystem/base.py +1 -2
  139. exonware/xwsystem/io/filesystem/local.py +3 -4
  140. exonware/xwsystem/io/folder/__init__.py +1 -1
  141. exonware/xwsystem/io/folder/base.py +1 -2
  142. exonware/xwsystem/io/folder/folder.py +16 -7
  143. exonware/xwsystem/io/indexing/__init__.py +14 -0
  144. exonware/xwsystem/io/indexing/facade.py +443 -0
  145. exonware/xwsystem/io/path_parser.py +98 -0
  146. exonware/xwsystem/io/serialization/__init__.py +21 -3
  147. exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
  148. exonware/xwsystem/io/serialization/base.py +84 -34
  149. exonware/xwsystem/io/serialization/contracts.py +50 -73
  150. exonware/xwsystem/io/serialization/defs.py +2 -1
  151. exonware/xwsystem/io/serialization/errors.py +2 -1
  152. exonware/xwsystem/io/serialization/flyweight.py +154 -7
  153. exonware/xwsystem/io/serialization/format_detector.py +15 -14
  154. exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
  155. exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
  156. exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
  157. exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
  158. exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
  159. exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
  160. exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
  161. exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
  162. exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
  163. exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
  164. exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
  165. exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
  166. exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
  167. exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
  168. exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
  169. exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
  170. exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
  171. exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
  172. exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
  173. exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
  174. exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
  175. exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
  176. exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
  177. exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
  178. exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
  179. exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
  180. exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
  181. exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
  182. exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
  183. exonware/xwsystem/io/serialization/parsers/base.py +6 -5
  184. exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
  185. exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
  186. exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
  187. exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
  188. exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
  189. exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
  190. exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
  191. exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
  192. exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
  193. exonware/xwsystem/io/serialization/registry.py +4 -4
  194. exonware/xwsystem/io/serialization/serializer.py +168 -79
  195. exonware/xwsystem/io/serialization/universal_options.py +367 -0
  196. exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
  197. exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
  198. exonware/xwsystem/io/source_reader.py +223 -0
  199. exonware/xwsystem/io/stream/__init__.py +1 -1
  200. exonware/xwsystem/io/stream/async_operations.py +61 -14
  201. exonware/xwsystem/io/stream/base.py +1 -2
  202. exonware/xwsystem/io/stream/codec_io.py +6 -7
  203. exonware/xwsystem/ipc/__init__.py +1 -0
  204. exonware/xwsystem/ipc/async_fabric.py +4 -4
  205. exonware/xwsystem/ipc/base.py +6 -5
  206. exonware/xwsystem/ipc/contracts.py +41 -66
  207. exonware/xwsystem/ipc/defs.py +2 -1
  208. exonware/xwsystem/ipc/errors.py +2 -1
  209. exonware/xwsystem/ipc/message_queue.py +5 -2
  210. exonware/xwsystem/ipc/pipes.py +70 -34
  211. exonware/xwsystem/ipc/process_manager.py +7 -5
  212. exonware/xwsystem/ipc/process_pool.py +6 -5
  213. exonware/xwsystem/ipc/shared_memory.py +64 -11
  214. exonware/xwsystem/monitoring/__init__.py +7 -0
  215. exonware/xwsystem/monitoring/base.py +11 -8
  216. exonware/xwsystem/monitoring/contracts.py +86 -144
  217. exonware/xwsystem/monitoring/defs.py +2 -1
  218. exonware/xwsystem/monitoring/error_recovery.py +16 -3
  219. exonware/xwsystem/monitoring/errors.py +2 -1
  220. exonware/xwsystem/monitoring/facade.py +183 -0
  221. exonware/xwsystem/monitoring/memory_monitor.py +1 -0
  222. exonware/xwsystem/monitoring/metrics.py +1 -0
  223. exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
  224. exonware/xwsystem/monitoring/performance_monitor.py +1 -0
  225. exonware/xwsystem/monitoring/performance_validator.py +1 -0
  226. exonware/xwsystem/monitoring/system_monitor.py +6 -5
  227. exonware/xwsystem/monitoring/tracing.py +18 -16
  228. exonware/xwsystem/monitoring/tracker.py +2 -1
  229. exonware/xwsystem/operations/__init__.py +5 -50
  230. exonware/xwsystem/operations/base.py +3 -44
  231. exonware/xwsystem/operations/contracts.py +25 -15
  232. exonware/xwsystem/operations/defs.py +1 -1
  233. exonware/xwsystem/operations/diff.py +5 -4
  234. exonware/xwsystem/operations/errors.py +1 -1
  235. exonware/xwsystem/operations/merge.py +6 -4
  236. exonware/xwsystem/operations/patch.py +5 -4
  237. exonware/xwsystem/patterns/__init__.py +1 -0
  238. exonware/xwsystem/patterns/base.py +2 -1
  239. exonware/xwsystem/patterns/context_manager.py +2 -1
  240. exonware/xwsystem/patterns/contracts.py +215 -256
  241. exonware/xwsystem/patterns/defs.py +2 -1
  242. exonware/xwsystem/patterns/dynamic_facade.py +1 -0
  243. exonware/xwsystem/patterns/errors.py +2 -4
  244. exonware/xwsystem/patterns/handler_factory.py +2 -3
  245. exonware/xwsystem/patterns/import_registry.py +1 -0
  246. exonware/xwsystem/patterns/object_pool.py +1 -0
  247. exonware/xwsystem/patterns/registry.py +4 -43
  248. exonware/xwsystem/plugins/__init__.py +2 -1
  249. exonware/xwsystem/plugins/base.py +6 -5
  250. exonware/xwsystem/plugins/contracts.py +94 -158
  251. exonware/xwsystem/plugins/defs.py +2 -1
  252. exonware/xwsystem/plugins/errors.py +2 -1
  253. exonware/xwsystem/py.typed +3 -0
  254. exonware/xwsystem/query/__init__.py +36 -0
  255. exonware/xwsystem/query/contracts.py +56 -0
  256. exonware/xwsystem/query/errors.py +22 -0
  257. exonware/xwsystem/query/registry.py +128 -0
  258. exonware/xwsystem/runtime/__init__.py +2 -1
  259. exonware/xwsystem/runtime/base.py +4 -3
  260. exonware/xwsystem/runtime/contracts.py +39 -60
  261. exonware/xwsystem/runtime/defs.py +2 -1
  262. exonware/xwsystem/runtime/env.py +11 -9
  263. exonware/xwsystem/runtime/errors.py +2 -1
  264. exonware/xwsystem/runtime/reflection.py +3 -2
  265. exonware/xwsystem/security/__init__.py +68 -11
  266. exonware/xwsystem/security/audit.py +167 -0
  267. exonware/xwsystem/security/base.py +121 -24
  268. exonware/xwsystem/security/contracts.py +91 -146
  269. exonware/xwsystem/security/crypto.py +17 -16
  270. exonware/xwsystem/security/defs.py +2 -1
  271. exonware/xwsystem/security/errors.py +2 -1
  272. exonware/xwsystem/security/facade.py +321 -0
  273. exonware/xwsystem/security/file_security.py +330 -0
  274. exonware/xwsystem/security/hazmat.py +11 -8
  275. exonware/xwsystem/security/monitor.py +372 -0
  276. exonware/xwsystem/security/path_validator.py +140 -18
  277. exonware/xwsystem/security/policy.py +357 -0
  278. exonware/xwsystem/security/resource_limits.py +1 -0
  279. exonware/xwsystem/security/validator.py +455 -0
  280. exonware/xwsystem/shared/__init__.py +14 -1
  281. exonware/xwsystem/shared/base.py +285 -2
  282. exonware/xwsystem/shared/contracts.py +415 -126
  283. exonware/xwsystem/shared/defs.py +2 -1
  284. exonware/xwsystem/shared/errors.py +2 -2
  285. exonware/xwsystem/shared/xwobject.py +316 -0
  286. exonware/xwsystem/structures/__init__.py +1 -0
  287. exonware/xwsystem/structures/base.py +3 -2
  288. exonware/xwsystem/structures/circular_detector.py +15 -14
  289. exonware/xwsystem/structures/contracts.py +53 -76
  290. exonware/xwsystem/structures/defs.py +2 -1
  291. exonware/xwsystem/structures/errors.py +2 -1
  292. exonware/xwsystem/structures/tree_walker.py +2 -1
  293. exonware/xwsystem/threading/__init__.py +21 -4
  294. exonware/xwsystem/threading/async_primitives.py +6 -5
  295. exonware/xwsystem/threading/base.py +3 -2
  296. exonware/xwsystem/threading/contracts.py +87 -143
  297. exonware/xwsystem/threading/defs.py +2 -1
  298. exonware/xwsystem/threading/errors.py +2 -1
  299. exonware/xwsystem/threading/facade.py +175 -0
  300. exonware/xwsystem/threading/locks.py +1 -0
  301. exonware/xwsystem/threading/safe_factory.py +1 -0
  302. exonware/xwsystem/utils/__init__.py +40 -0
  303. exonware/xwsystem/utils/base.py +22 -21
  304. exonware/xwsystem/utils/contracts.py +50 -73
  305. exonware/xwsystem/utils/dt/__init__.py +19 -3
  306. exonware/xwsystem/utils/dt/base.py +5 -4
  307. exonware/xwsystem/utils/dt/contracts.py +22 -29
  308. exonware/xwsystem/utils/dt/defs.py +2 -1
  309. exonware/xwsystem/utils/dt/errors.py +2 -5
  310. exonware/xwsystem/utils/dt/formatting.py +88 -2
  311. exonware/xwsystem/utils/dt/humanize.py +10 -9
  312. exonware/xwsystem/utils/dt/parsing.py +56 -5
  313. exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
  314. exonware/xwsystem/utils/errors.py +2 -4
  315. exonware/xwsystem/utils/paths.py +1 -0
  316. exonware/xwsystem/utils/string.py +49 -0
  317. exonware/xwsystem/utils/test_runner.py +185 -0
  318. exonware/xwsystem/utils/utils_contracts.py +2 -1
  319. exonware/xwsystem/utils/web.py +110 -0
  320. exonware/xwsystem/validation/__init__.py +25 -1
  321. exonware/xwsystem/validation/base.py +6 -5
  322. exonware/xwsystem/validation/contracts.py +29 -41
  323. exonware/xwsystem/validation/data_validator.py +1 -0
  324. exonware/xwsystem/validation/declarative.py +11 -8
  325. exonware/xwsystem/validation/defs.py +2 -1
  326. exonware/xwsystem/validation/errors.py +2 -1
  327. exonware/xwsystem/validation/facade.py +198 -0
  328. exonware/xwsystem/validation/fluent_validator.py +22 -19
  329. exonware/xwsystem/validation/schema_discovery.py +210 -0
  330. exonware/xwsystem/validation/type_safety.py +2 -1
  331. exonware/xwsystem/version.py +2 -2
  332. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
  333. exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
  334. exonware/xwsystem/cli/__init__.py +0 -43
  335. exonware/xwsystem/cli/console.py +0 -113
  336. exonware/xwsystem/cli/defs.py +0 -134
  337. exonware/xwsystem/conf.py +0 -44
  338. exonware/xwsystem/security/auth.py +0 -484
  339. exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
  340. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
  341. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,443 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/indexing/facade.py
2
+ """
3
+ Company: eXonware.com
4
+ Author: Eng. Muhammad AlShehri
5
+ Email: connect@exonware.com
6
+ Version: 0.1.0.4
7
+ Generation Date: January 2026
8
+
9
+ XWIndex - Unified Indexing Facade
10
+
11
+ Simplified API for indexing line-oriented files (JSONL/NDJSON):
12
+ - Build indexes with line offsets
13
+ - ID-based indexing
14
+ - Paging support
15
+ - Streaming operations
16
+ """
17
+
18
+ from pathlib import Path
19
+ from typing import Any, Optional, Callable, List, Iterator
20
+
21
+ from ..data_operations import (
22
+ ADataOperations,
23
+ JsonIndex,
24
+ JsonIndexMeta,
25
+ JsonMatchFn,
26
+ JsonUpdateFn,
27
+ )
28
+ from ..serialization.parsers.registry import get_best_available_parser
29
+ from ...config.logging_setup import get_logger
30
+
31
+ logger = get_logger(__name__)
32
+
33
+
34
+ class JsonlDataOperations(ADataOperations):
35
+ """Concrete implementation for JSONL/NDJSON files."""
36
+
37
+ def stream_read(
38
+ self,
39
+ file_path: str | Path,
40
+ match: JsonMatchFn,
41
+ path: Optional[List[object]] = None,
42
+ encoding: str = "utf-8",
43
+ ) -> Any:
44
+ """Return the first record that matches the predicate."""
45
+ parser = get_best_available_parser()
46
+
47
+ with open(file_path, "r", encoding=encoding) as f:
48
+ for line in f:
49
+ line = line.strip()
50
+ if not line:
51
+ continue
52
+
53
+ try:
54
+ obj = parser.loads(line)
55
+ if match(obj):
56
+ return obj
57
+ except Exception:
58
+ continue
59
+
60
+ return None
61
+
62
+ def stream_update(
63
+ self,
64
+ file_path: str | Path,
65
+ match: JsonMatchFn,
66
+ updater: JsonUpdateFn,
67
+ *,
68
+ encoding: str = "utf-8",
69
+ newline: str = "\n",
70
+ atomic: bool = True,
71
+ ) -> int:
72
+ """Stream-copy the backing store, applying updater to matching records."""
73
+ import tempfile
74
+ import shutil
75
+
76
+ parser = get_best_available_parser()
77
+ updated_count = 0
78
+
79
+ file_path = Path(file_path)
80
+ temp_path = file_path.with_suffix(file_path.suffix + ".tmp")
81
+
82
+ try:
83
+ with open(file_path, "r", encoding=encoding) as infile, \
84
+ open(temp_path, "w", encoding=encoding) as outfile:
85
+
86
+ for line in infile:
87
+ original_line = line
88
+ line = line.strip()
89
+
90
+ if not line:
91
+ outfile.write(original_line)
92
+ continue
93
+
94
+ try:
95
+ obj = parser.loads(line)
96
+ if match(obj):
97
+ updated_obj = updater(obj)
98
+ updated_line = parser.dumps(updated_obj) + newline
99
+ outfile.write(updated_line)
100
+ updated_count += 1
101
+ else:
102
+ outfile.write(original_line)
103
+ except Exception:
104
+ outfile.write(original_line)
105
+
106
+ if atomic:
107
+ shutil.move(str(temp_path), str(file_path))
108
+ else:
109
+ shutil.copy2(str(temp_path), str(file_path))
110
+ temp_path.unlink()
111
+
112
+ except Exception as e:
113
+ if temp_path.exists():
114
+ temp_path.unlink()
115
+ raise
116
+
117
+ return updated_count
118
+
119
+ def build_index(
120
+ self,
121
+ file_path: str | Path,
122
+ *,
123
+ encoding: str = "utf-8",
124
+ id_field: str | None = None,
125
+ max_id_index: int | None = None,
126
+ ) -> JsonIndex:
127
+ """Build an index structure suitable for random access and paging."""
128
+ import os
129
+ import time
130
+
131
+ parser = get_best_available_parser()
132
+ file_path = Path(file_path)
133
+
134
+ line_offsets: List[int] = []
135
+ id_index: Optional[dict[str, int]] = {} if id_field else None
136
+
137
+ stat = file_path.stat()
138
+ size = stat.st_size
139
+ mtime = stat.st_mtime
140
+
141
+ with open(file_path, "rb") as f:
142
+ current_offset = 0
143
+
144
+ while True:
145
+ line_start = current_offset
146
+ line = f.readline()
147
+
148
+ if not line:
149
+ break
150
+
151
+ current_offset = f.tell()
152
+
153
+ # Skip empty lines
154
+ if not line.strip():
155
+ continue
156
+
157
+ line_offsets.append(line_start)
158
+ line_idx = len(line_offsets) - 1
159
+
160
+ # Build ID index if requested
161
+ if id_field and id_index is not None:
162
+ if max_id_index is None or len(id_index) < max_id_index:
163
+ try:
164
+ obj = parser.loads(line)
165
+ if isinstance(obj, dict) and id_field in obj:
166
+ id_val = str(obj[id_field])
167
+ id_index[id_val] = line_idx
168
+ except Exception:
169
+ pass
170
+
171
+ meta = JsonIndexMeta(
172
+ path=str(file_path),
173
+ size=size,
174
+ mtime=mtime,
175
+ version=1
176
+ )
177
+
178
+ return JsonIndex(
179
+ meta=meta,
180
+ line_offsets=line_offsets,
181
+ id_index=id_index if id_index else None
182
+ )
183
+
184
+ def indexed_get_by_line(
185
+ self,
186
+ file_path: str | Path,
187
+ line_number: int,
188
+ *,
189
+ encoding: str = "utf-8",
190
+ index: Optional[JsonIndex] = None,
191
+ ) -> Any:
192
+ """Random-access a specific record by line number."""
193
+ parser = get_best_available_parser()
194
+
195
+ if index is None:
196
+ index = self.build_index(file_path, encoding=encoding)
197
+
198
+ if line_number < 0 or line_number >= len(index.line_offsets):
199
+ return None
200
+
201
+ offset = index.line_offsets[line_number]
202
+
203
+ with open(file_path, "rb") as f:
204
+ f.seek(offset)
205
+ line = f.readline().decode(encoding).strip()
206
+
207
+ if not line:
208
+ return None
209
+
210
+ try:
211
+ return parser.loads(line)
212
+ except Exception:
213
+ return None
214
+
215
+ def indexed_get_by_id(
216
+ self,
217
+ file_path: str | Path,
218
+ id_value: Any,
219
+ *,
220
+ encoding: str = "utf-8",
221
+ id_field: str = "id",
222
+ index: Optional[JsonIndex] = None,
223
+ ) -> Any:
224
+ """Random-access a record by logical ID."""
225
+ if index is None:
226
+ index = self.build_index(file_path, encoding=encoding, id_field=id_field)
227
+
228
+ if index.id_index is None:
229
+ # Fallback to linear scan
230
+ return self.stream_read(
231
+ file_path,
232
+ match=lambda obj: isinstance(obj, dict) and obj.get(id_field) == id_value,
233
+ encoding=encoding
234
+ )
235
+
236
+ id_str = str(id_value)
237
+ if id_str not in index.id_index:
238
+ return None
239
+
240
+ line_number = index.id_index[id_str]
241
+ return self.indexed_get_by_line(file_path, line_number, encoding=encoding, index=index)
242
+
243
+ def get_page(
244
+ self,
245
+ file_path: str | Path,
246
+ page_number: int,
247
+ page_size: int,
248
+ *,
249
+ encoding: str = "utf-8",
250
+ index: Optional[JsonIndex] = None,
251
+ ) -> List[Any]:
252
+ """Return a page of records using index."""
253
+ if index is None:
254
+ index = self.build_index(file_path, encoding=encoding)
255
+
256
+ start_idx = page_number * page_size
257
+ end_idx = start_idx + page_size
258
+
259
+ results = []
260
+ for line_number in range(start_idx, min(end_idx, len(index.line_offsets))):
261
+ record = self.indexed_get_by_line(file_path, line_number, encoding=encoding, index=index)
262
+ if record is not None:
263
+ results.append(record)
264
+
265
+ return results
266
+
267
+
268
+ class XWIndex:
269
+ """
270
+ Unified indexing facade - simple API for indexing line-oriented files.
271
+
272
+ Examples:
273
+ >>> # Simple indexing
274
+ >>> index = XWIndex("data.jsonl") # Auto-detects JSONL
275
+ >>> index = XWIndex("data.ndjson", format="jsonl")
276
+
277
+ >>> # Build index
278
+ >>> index.build() # Builds line offsets + optional ID index
279
+
280
+ >>> # Query
281
+ >>> record = index.get_by_line(42)
282
+ >>> record = index.get_by_id("user_123")
283
+
284
+ >>> # Paging
285
+ >>> page = index.get_page(page=1, size=10)
286
+
287
+ >>> # Streaming
288
+ >>> for record in index.stream(match=lambda r: r["active"]):
289
+ ... print(record)
290
+ """
291
+
292
+ def __init__(
293
+ self,
294
+ file_path: str | Path,
295
+ *,
296
+ format: Optional[str] = None,
297
+ encoding: str = "utf-8",
298
+ id_field: Optional[str] = None,
299
+ ):
300
+ """
301
+ Initialize unified index.
302
+
303
+ Args:
304
+ file_path: Path to line-oriented file (JSONL/NDJSON)
305
+ format: File format ("jsonl", "ndjson") - auto-detected if None
306
+ encoding: File encoding (default: "utf-8")
307
+ id_field: Optional field name for ID-based indexing
308
+ """
309
+ self.file_path = Path(file_path)
310
+ self.format = format or self._detect_format()
311
+ self.encoding = encoding
312
+ self.id_field = id_field
313
+
314
+ self._operations = JsonlDataOperations()
315
+ self._index: Optional[JsonIndex] = None
316
+
317
+ def _detect_format(self) -> str:
318
+ """Auto-detect format from file extension."""
319
+ ext = self.file_path.suffix.lower()
320
+ if ext in (".jsonl", ".ndjson", ".jsonlines"):
321
+ return "jsonl"
322
+ return "jsonl" # Default to JSONL
323
+
324
+ def build(
325
+ self,
326
+ *,
327
+ id_field: Optional[str] = None,
328
+ max_id_index: Optional[int] = None,
329
+ force: bool = False,
330
+ ) -> JsonIndex:
331
+ """
332
+ Build index structure.
333
+
334
+ Args:
335
+ id_field: Field name for ID-based indexing (uses instance id_field if None)
336
+ max_id_index: Maximum number of IDs to index
337
+ force: Force rebuild even if index exists
338
+
339
+ Returns:
340
+ JsonIndex object
341
+ """
342
+ if self._index is None or force:
343
+ self._index = self._operations.build_index(
344
+ self.file_path,
345
+ encoding=self.encoding,
346
+ id_field=id_field or self.id_field,
347
+ max_id_index=max_id_index,
348
+ )
349
+
350
+ return self._index
351
+
352
+ def get_by_line(self, line_number: int) -> Any:
353
+ """Get record by line number (0-based)."""
354
+ if self._index is None:
355
+ self.build()
356
+
357
+ return self._operations.indexed_get_by_line(
358
+ self.file_path,
359
+ line_number,
360
+ encoding=self.encoding,
361
+ index=self._index,
362
+ )
363
+
364
+ def get_by_id(self, id_value: Any, id_field: Optional[str] = None) -> Any:
365
+ """Get record by ID."""
366
+ if self._index is None:
367
+ self.build(id_field=id_field or self.id_field)
368
+
369
+ return self._operations.indexed_get_by_id(
370
+ self.file_path,
371
+ id_value,
372
+ encoding=self.encoding,
373
+ id_field=id_field or self.id_field or "id",
374
+ index=self._index,
375
+ )
376
+
377
+ def get_page(self, page: int = 0, size: int = 10) -> List[Any]:
378
+ """Get a page of records."""
379
+ if self._index is None:
380
+ self.build()
381
+
382
+ return self._operations.get_page(
383
+ self.file_path,
384
+ page,
385
+ size,
386
+ encoding=self.encoding,
387
+ index=self._index,
388
+ )
389
+
390
+ def stream(self, match: Optional[Callable[[Any], bool]] = None) -> Iterator[Any]:
391
+ """
392
+ Stream records matching predicate.
393
+
394
+ Args:
395
+ match: Optional predicate function (returns all records if None)
396
+ """
397
+ parser = get_best_available_parser()
398
+
399
+ with open(self.file_path, "r", encoding=self.encoding) as f:
400
+ for line in f:
401
+ line = line.strip()
402
+ if not line:
403
+ continue
404
+
405
+ try:
406
+ obj = parser.loads(line)
407
+ if match is None or match(obj):
408
+ yield obj
409
+ except Exception:
410
+ continue
411
+
412
+ def update(
413
+ self,
414
+ match: Callable[[Any], bool],
415
+ updater: Callable[[Any], Any],
416
+ *,
417
+ atomic: bool = True,
418
+ ) -> int:
419
+ """
420
+ Update records matching predicate.
421
+
422
+ Args:
423
+ match: Predicate function to match records
424
+ updater: Function to update matched records
425
+ atomic: Use atomic file replacement
426
+
427
+ Returns:
428
+ Number of updated records
429
+ """
430
+ return self._operations.stream_update(
431
+ self.file_path,
432
+ match,
433
+ updater,
434
+ encoding=self.encoding,
435
+ atomic=atomic,
436
+ )
437
+
438
+ @property
439
+ def index(self) -> Optional[JsonIndex]:
440
+ """Get current index (builds if needed)."""
441
+ if self._index is None:
442
+ self.build()
443
+ return self._index
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ #exonware/xwsystem/src/exonware/xwsystem/io/path_parser.py
4
+
5
+ Generic Path Parser for xwsystem.
6
+
7
+ Provides thread-safe path parsing with caching that can be used by any library.
8
+
9
+ Company: eXonware.com
10
+ Author: Eng. Muhammad AlShehri
11
+ Email: connect@exonware.com
12
+ Version: 0.1.0.4
13
+ Generation Date: 26-Jan-2025
14
+ """
15
+
16
+ import threading
17
+ from typing import List
18
+ from exonware.xwsystem.caching import create_cache
19
+ from exonware.xwsystem import get_logger
20
+
21
+ logger = get_logger(__name__)
22
+
23
+
24
+ class PathParser:
25
+ """
26
+ Thread-safe path parser with caching.
27
+
28
+ Performance Optimization:
29
+ - Uses xwsystem create_cache() for 10-50x faster cache operations
30
+ - Automatic LRU eviction when capacity is reached
31
+ - Thread-safe by default (via xwsystem cache)
32
+
33
+ Can be used by any library for path parsing operations.
34
+ """
35
+
36
+ def __init__(self, max_cache_size: int = 1024, namespace: str = "xwsystem"):
37
+ """
38
+ Initialize path parser.
39
+
40
+ Args:
41
+ max_cache_size: Maximum cache size
42
+ namespace: Cache namespace
43
+ """
44
+ # Use xwsystem optimized cache for 10-50x faster operations
45
+ # Provides automatic LRU eviction and thread-safety
46
+ self._cache = create_cache(
47
+ capacity=max_cache_size,
48
+ namespace=namespace,
49
+ name='path_parser_cache'
50
+ )
51
+ self._max_cache_size = max_cache_size
52
+ # Lock for potential future stats tracking if needed
53
+ self._lock = threading.RLock()
54
+
55
+ def parse(self, path: str) -> List[str]:
56
+ """
57
+ Parse a path string into parts (O(1) cache lookup with xwsystem cache).
58
+
59
+ Args:
60
+ path: Path string to parse
61
+
62
+ Returns:
63
+ List of path parts
64
+ """
65
+ # Check xwsystem cache first (O(1) with automatic LRU eviction)
66
+ cached_parts = self._cache.get(path)
67
+ if cached_parts is not None:
68
+ return cached_parts
69
+
70
+ # Cache miss - parse path
71
+ parts = self._parse_path(path)
72
+
73
+ # Cache the result (automatic LRU eviction when full)
74
+ self._cache.put(path, parts)
75
+
76
+ return parts
77
+
78
+ def _parse_path(self, path: str) -> List[str]:
79
+ """
80
+ Internal path parsing logic.
81
+
82
+ Args:
83
+ path: Path string to parse
84
+
85
+ Returns:
86
+ List of path parts
87
+ """
88
+ if not path:
89
+ return []
90
+
91
+ # Simple dot-separated path parsing
92
+ return [part for part in path.split('.') if part]
93
+
94
+ def clear_cache(self) -> None:
95
+ """Clear the path parser cache."""
96
+ # Clear cache (implementation depends on cache type)
97
+ if hasattr(self._cache, 'clear'):
98
+ self._cache.clear()
@@ -1,8 +1,9 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/io/serialization/__init__.py
1
2
  """
2
3
  Company: eXonware.com
3
4
  Author: Eng. Muhammad AlShehri
4
5
  Email: connect@exonware.com
5
- Version: 0.1.0.1
6
+ Version: 0.1.0.4
6
7
  Generation Date: November 2, 2025
7
8
 
8
9
  Serialization module - 29+ serialization formats with I→A→XW pattern.
@@ -23,6 +24,16 @@ from .base import ASerialization, ASchemaRegistry
23
24
  # Registry
24
25
  from .registry import SerializationRegistry, get_serialization_registry
25
26
 
27
+ # Universal options
28
+ from .universal_options import (
29
+ map_universal_options,
30
+ get_supported_universal_options,
31
+ validate_universal_options,
32
+ get_all_supported_formats,
33
+ get_format_option_info,
34
+ UniversalOption,
35
+ )
36
+
26
37
  # NOTE: Schema Registry moved to exonware-xwschema
27
38
  # from .schema_registry import (
28
39
  # SchemaInfo,
@@ -106,7 +117,7 @@ for _serializer_class in [
106
117
  pass # Skip if already registered or missing dependencies
107
118
 
108
119
  # NOTE: xwformats auto-discovery removed per DEV_GUIDELINES.md
109
- # "NO TRY/EXCEPT FOR IMPORTS" - Users should explicitly import xwformats when needed:
120
+ # "NO TRY/EXCEPT FOR IMPORTS" - Users explicitly import xwformats when needed:
110
121
  # from exonware.xwformats import AvroSerializer, ProtobufSerializer, ...
111
122
  # xwformats auto-registers its formats on import
112
123
 
@@ -160,6 +171,14 @@ __all__ = [
160
171
  "detect_format",
161
172
  "AutoSerializer",
162
173
  "XWSerializer",
174
+
175
+ # Universal options
176
+ "map_universal_options",
177
+ "get_supported_universal_options",
178
+ "validate_universal_options",
179
+ "get_all_supported_formats",
180
+ "get_format_option_info",
181
+ "UniversalOption",
163
182
  ]
164
183
 
165
184
  # NOTE: Enterprise formats available in exonware-xwformats:
@@ -169,4 +188,3 @@ __all__ = [
169
188
  # - Binary: UBJSON (1 format)
170
189
  # Total: 16 enterprise formats (~87 MB)
171
190
  # Install with: pip install exonware-xwformats
172
-