synapse-storage 3.0.19 → 4.0.0

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 (351) hide show
  1. package/README.md +661 -104
  2. package/dist/_utils/chunk.util.d.ts +8 -0
  3. package/dist/_utils/chunk.util.d.ts.map +1 -0
  4. package/dist/_utils/chunk.util.js +21 -0
  5. package/dist/_utils/chunk.util.js.map +1 -0
  6. package/dist/_utils/deepMerge.util.d.ts +2 -0
  7. package/dist/_utils/deepMerge.util.d.ts.map +1 -0
  8. package/dist/_utils/deepMerge.util.js +19 -0
  9. package/dist/_utils/deepMerge.util.js.map +1 -0
  10. package/dist/_utils/error-handling.util.d.ts +50 -0
  11. package/dist/_utils/error-handling.util.d.ts.map +1 -0
  12. package/dist/_utils/error-handling.util.js +67 -0
  13. package/dist/_utils/error-handling.util.js.map +1 -0
  14. package/dist/_utils/flatMap.util.d.ts +10 -0
  15. package/dist/_utils/flatMap.util.d.ts.map +1 -0
  16. package/dist/_utils/flatMap.util.js +23 -0
  17. package/dist/_utils/flatMap.util.js.map +1 -0
  18. package/dist/_utils/index.d.ts +6 -0
  19. package/dist/_utils/index.d.ts.map +1 -0
  20. package/dist/_utils/index.js +13 -0
  21. package/dist/_utils/index.js.map +1 -0
  22. package/dist/_utils/logger-console.util.d.ts +9 -0
  23. package/dist/_utils/logger-console.util.d.ts.map +1 -0
  24. package/dist/_utils/logger-console.util.js +14 -0
  25. package/dist/_utils/logger-console.util.js.map +1 -0
  26. package/dist/api/api.module.d.ts +46 -0
  27. package/dist/api/api.module.d.ts.map +1 -0
  28. package/dist/api/api.module.js +121 -0
  29. package/dist/api/api.module.js.map +1 -0
  30. package/dist/api/components/endpoint.d.ts +57 -0
  31. package/dist/api/components/endpoint.d.ts.map +1 -0
  32. package/dist/api/components/endpoint.js +385 -0
  33. package/dist/api/components/endpoint.js.map +1 -0
  34. package/dist/api/components/query-storage.d.ts +100 -0
  35. package/dist/api/components/query-storage.d.ts.map +1 -0
  36. package/dist/api/components/query-storage.js +293 -0
  37. package/dist/api/components/query-storage.js.map +1 -0
  38. package/dist/api/example.d.ts +83 -0
  39. package/dist/api/example.d.ts.map +1 -0
  40. package/dist/api/example.js +90 -0
  41. package/dist/api/example.js.map +1 -0
  42. package/dist/api/index.d.ts +4 -0
  43. package/dist/api/index.d.ts.map +1 -0
  44. package/dist/api/index.js +11 -0
  45. package/dist/api/index.js.map +1 -0
  46. package/dist/api/types/api.interface.d.ts +126 -0
  47. package/dist/api/types/api.interface.d.ts.map +1 -0
  48. package/dist/api/types/api.interface.js +15 -0
  49. package/dist/api/types/api.interface.js.map +1 -0
  50. package/dist/api/types/endpoint.interface.d.ts +118 -0
  51. package/dist/api/types/endpoint.interface.d.ts.map +1 -0
  52. package/dist/api/types/endpoint.interface.js +6 -0
  53. package/dist/api/types/endpoint.interface.js.map +1 -0
  54. package/dist/api/types/query.interface.d.ts +85 -0
  55. package/dist/api/types/query.interface.d.ts.map +1 -0
  56. package/dist/api/types/query.interface.js +6 -0
  57. package/dist/api/types/query.interface.js.map +1 -0
  58. package/dist/api/utils/api-helpers.d.ts +22 -0
  59. package/dist/api/utils/api-helpers.d.ts.map +1 -0
  60. package/dist/api/utils/api-helpers.js +44 -0
  61. package/dist/api/utils/api-helpers.js.map +1 -0
  62. package/dist/api/utils/create-header-context.d.ts +10 -0
  63. package/dist/api/utils/create-header-context.d.ts.map +1 -0
  64. package/dist/api/utils/create-header-context.js +40 -0
  65. package/dist/api/utils/create-header-context.js.map +1 -0
  66. package/dist/api/utils/endpoint-headers.d.ts +23 -0
  67. package/dist/api/utils/endpoint-headers.d.ts.map +1 -0
  68. package/dist/api/utils/endpoint-headers.js +61 -0
  69. package/dist/api/utils/endpoint-headers.js.map +1 -0
  70. package/dist/api/utils/fetch-base-query.d.ts +9 -0
  71. package/dist/api/utils/fetch-base-query.d.ts.map +1 -0
  72. package/dist/api/utils/fetch-base-query.js +242 -0
  73. package/dist/api/utils/fetch-base-query.js.map +1 -0
  74. package/dist/api/utils/file-utils.d.ts +43 -0
  75. package/dist/api/utils/file-utils.d.ts.map +1 -0
  76. package/dist/api/utils/file-utils.js +102 -0
  77. package/dist/api/utils/file-utils.js.map +1 -0
  78. package/dist/api/utils/get-cacheable-headers.d.ts +8 -0
  79. package/dist/api/utils/get-cacheable-headers.d.ts.map +1 -0
  80. package/dist/api/utils/get-cacheable-headers.js +23 -0
  81. package/dist/api/utils/get-cacheable-headers.js.map +1 -0
  82. package/dist/core/index.d.ts +3 -0
  83. package/dist/core/index.d.ts.map +1 -0
  84. package/dist/core/index.js +7 -0
  85. package/dist/core/index.js.map +1 -0
  86. package/dist/core/selector/index.d.ts +3 -0
  87. package/dist/core/selector/index.d.ts.map +1 -0
  88. package/dist/core/selector/index.js +5 -0
  89. package/dist/core/selector/index.js.map +1 -0
  90. package/dist/{selector.interface-CA5y-kD_.d.ts → core/selector/selector.interface.d.ts} +41 -8
  91. package/dist/core/selector/selector.interface.d.ts.map +1 -0
  92. package/dist/core/selector/selector.interface.js +7 -0
  93. package/dist/core/selector/selector.interface.js.map +1 -0
  94. package/dist/core/selector/selector.module.d.ts +36 -0
  95. package/dist/core/selector/selector.module.d.ts.map +1 -0
  96. package/dist/core/selector/selector.module.js +412 -0
  97. package/dist/core/selector/selector.module.js.map +1 -0
  98. package/dist/core/storage/adapters/async-base-storage.service.d.ts +49 -0
  99. package/dist/core/storage/adapters/async-base-storage.service.d.ts.map +1 -0
  100. package/dist/core/storage/adapters/async-base-storage.service.js +505 -0
  101. package/dist/core/storage/adapters/async-base-storage.service.js.map +1 -0
  102. package/dist/core/storage/adapters/indexed-DB.service.d.ts +89 -0
  103. package/dist/core/storage/adapters/indexed-DB.service.d.ts.map +1 -0
  104. package/dist/core/storage/adapters/indexed-DB.service.js +596 -0
  105. package/dist/core/storage/adapters/indexed-DB.service.js.map +1 -0
  106. package/dist/core/storage/adapters/local-storage.service.d.ts +23 -0
  107. package/dist/core/storage/adapters/local-storage.service.d.ts.map +1 -0
  108. package/dist/core/storage/adapters/local-storage.service.js +111 -0
  109. package/dist/core/storage/adapters/local-storage.service.js.map +1 -0
  110. package/dist/core/storage/adapters/memory-storage.service.d.ts +24 -0
  111. package/dist/core/storage/adapters/memory-storage.service.d.ts.map +1 -0
  112. package/dist/core/storage/adapters/memory-storage.service.js +110 -0
  113. package/dist/core/storage/adapters/memory-storage.service.js.map +1 -0
  114. package/dist/core/storage/adapters/path.utils.d.ts +5 -0
  115. package/dist/core/storage/adapters/path.utils.d.ts.map +1 -0
  116. package/dist/core/storage/adapters/path.utils.js +42 -0
  117. package/dist/core/storage/adapters/path.utils.js.map +1 -0
  118. package/dist/core/storage/adapters/storage-core.d.ts +61 -0
  119. package/dist/core/storage/adapters/storage-core.d.ts.map +1 -0
  120. package/dist/core/storage/adapters/storage-core.js +221 -0
  121. package/dist/core/storage/adapters/storage-core.js.map +1 -0
  122. package/dist/core/storage/adapters/sync-base-storage.service.d.ts +56 -0
  123. package/dist/core/storage/adapters/sync-base-storage.service.d.ts.map +1 -0
  124. package/dist/core/storage/adapters/sync-base-storage.service.js +481 -0
  125. package/dist/core/storage/adapters/sync-base-storage.service.js.map +1 -0
  126. package/dist/core/storage/index.d.ts +16 -0
  127. package/dist/core/storage/index.d.ts.map +1 -0
  128. package/dist/core/storage/index.js +38 -0
  129. package/dist/core/storage/index.js.map +1 -0
  130. package/dist/core/storage/middlewares/broadcast.middleware.d.ts +9 -0
  131. package/dist/core/storage/middlewares/broadcast.middleware.d.ts.map +1 -0
  132. package/dist/core/storage/middlewares/broadcast.middleware.js +197 -0
  133. package/dist/core/storage/middlewares/broadcast.middleware.js.map +1 -0
  134. package/dist/core/storage/middlewares/index.d.ts +9 -0
  135. package/dist/core/storage/middlewares/index.d.ts.map +1 -0
  136. package/dist/core/storage/middlewares/index.js +17 -0
  137. package/dist/core/storage/middlewares/index.js.map +1 -0
  138. package/dist/core/storage/middlewares/storage-batching.middleware.d.ts +7 -0
  139. package/dist/core/storage/middlewares/storage-batching.middleware.d.ts.map +1 -0
  140. package/dist/core/storage/middlewares/storage-batching.middleware.js +108 -0
  141. package/dist/core/storage/middlewares/storage-batching.middleware.js.map +1 -0
  142. package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts +7 -0
  143. package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts.map +1 -0
  144. package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js +43 -0
  145. package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js.map +1 -0
  146. package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts +9 -0
  147. package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts.map +1 -0
  148. package/dist/core/storage/middlewares/sync-broadcast.middleware.js +177 -0
  149. package/dist/core/storage/middlewares/sync-broadcast.middleware.js.map +1 -0
  150. package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts +6 -0
  151. package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts.map +1 -0
  152. package/dist/core/storage/middlewares/sync-storage-batching.middleware.js +56 -0
  153. package/dist/core/storage/middlewares/sync-storage-batching.middleware.js.map +1 -0
  154. package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts +7 -0
  155. package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts.map +1 -0
  156. package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js +39 -0
  157. package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js.map +1 -0
  158. package/dist/core/storage/modules/plugin/plugin.interface.d.ts +101 -0
  159. package/dist/core/storage/modules/plugin/plugin.interface.d.ts.map +1 -0
  160. package/dist/core/storage/modules/plugin/plugin.interface.js +8 -0
  161. package/dist/core/storage/modules/plugin/plugin.interface.js.map +1 -0
  162. package/dist/core/storage/modules/plugin/plugin.service.d.ts +49 -0
  163. package/dist/core/storage/modules/plugin/plugin.service.d.ts.map +1 -0
  164. package/dist/core/storage/modules/plugin/plugin.service.js +406 -0
  165. package/dist/core/storage/modules/plugin/plugin.service.js.map +1 -0
  166. package/dist/core/storage/modules/singleton/mixin.util.d.ts +6 -0
  167. package/dist/core/storage/modules/singleton/mixin.util.d.ts.map +1 -0
  168. package/dist/core/storage/modules/singleton/mixin.util.js +30 -0
  169. package/dist/core/storage/modules/singleton/mixin.util.js.map +1 -0
  170. package/dist/core/storage/modules/singleton/models.d.ts +143 -0
  171. package/dist/core/storage/modules/singleton/models.d.ts.map +1 -0
  172. package/dist/core/storage/modules/singleton/models.js +60 -0
  173. package/dist/core/storage/modules/singleton/models.js.map +1 -0
  174. package/dist/core/storage/modules/singleton/singleton.util.d.ts +36 -0
  175. package/dist/core/storage/modules/singleton/singleton.util.d.ts.map +1 -0
  176. package/dist/core/storage/modules/singleton/singleton.util.js +216 -0
  177. package/dist/core/storage/modules/singleton/singleton.util.js.map +1 -0
  178. package/dist/core/storage/storage.interface.d.ts +168 -0
  179. package/dist/core/storage/storage.interface.d.ts.map +1 -0
  180. package/dist/core/storage/storage.interface.js +23 -0
  181. package/dist/core/storage/storage.interface.js.map +1 -0
  182. package/dist/core/storage/utils/broadcast.util.d.ts +49 -0
  183. package/dist/core/storage/utils/broadcast.util.d.ts.map +1 -0
  184. package/dist/core/storage/utils/broadcast.util.js +141 -0
  185. package/dist/core/storage/utils/broadcast.util.js.map +1 -0
  186. package/dist/core/storage/utils/cache.util.d.ts +33 -0
  187. package/dist/core/storage/utils/cache.util.d.ts.map +1 -0
  188. package/dist/core/storage/utils/cache.util.js +54 -0
  189. package/dist/core/storage/utils/cache.util.js.map +1 -0
  190. package/dist/core/storage/utils/middleware-module.d.ts +94 -0
  191. package/dist/core/storage/utils/middleware-module.d.ts.map +1 -0
  192. package/dist/core/storage/utils/middleware-module.js +258 -0
  193. package/dist/core/storage/utils/middleware-module.js.map +1 -0
  194. package/dist/core/storage/utils/path-selector.util.d.ts +15 -0
  195. package/dist/core/storage/utils/path-selector.util.d.ts.map +1 -0
  196. package/dist/core/storage/utils/path-selector.util.js +58 -0
  197. package/dist/core/storage/utils/path-selector.util.js.map +1 -0
  198. package/dist/core/storage/utils/state-diff.util.d.ts +14 -0
  199. package/dist/core/storage/utils/state-diff.util.d.ts.map +1 -0
  200. package/dist/core/storage/utils/state-diff.util.js +88 -0
  201. package/dist/core/storage/utils/state-diff.util.js.map +1 -0
  202. package/dist/core/storage/utils/storage-factory.util.d.ts +21 -0
  203. package/dist/core/storage/utils/storage-factory.util.d.ts.map +1 -0
  204. package/dist/core/storage/utils/storage-factory.util.js +40 -0
  205. package/dist/core/storage/utils/storage-factory.util.js.map +1 -0
  206. package/dist/core/storage/utils/storage-key.d.ts +11 -0
  207. package/dist/core/storage/utils/storage-key.d.ts.map +1 -0
  208. package/dist/core/storage/utils/storage-key.js +24 -0
  209. package/dist/core/storage/utils/storage-key.js.map +1 -0
  210. package/dist/core/storage/utils/storage.utils.d.ts +17 -0
  211. package/dist/core/storage/utils/storage.utils.d.ts.map +1 -0
  212. package/dist/core/storage/utils/storage.utils.js +57 -0
  213. package/dist/core/storage/utils/storage.utils.js.map +1 -0
  214. package/dist/index.d.ts +10 -12
  215. package/dist/index.d.ts.map +1 -0
  216. package/dist/index.js +17 -1
  217. package/dist/index.js.map +1 -0
  218. package/dist/react/hooks/index.d.ts +5 -0
  219. package/dist/react/hooks/index.d.ts.map +1 -0
  220. package/dist/react/hooks/index.js +11 -0
  221. package/dist/react/hooks/index.js.map +1 -0
  222. package/dist/react/hooks/useCreateStorage.d.ts +39 -0
  223. package/dist/react/hooks/useCreateStorage.d.ts.map +1 -0
  224. package/dist/react/hooks/useCreateStorage.js +137 -0
  225. package/dist/react/hooks/useCreateStorage.js.map +1 -0
  226. package/dist/react/hooks/useSelector.d.ts +21 -0
  227. package/dist/react/hooks/useSelector.d.ts.map +1 -0
  228. package/dist/react/hooks/useSelector.js +56 -0
  229. package/dist/react/hooks/useSelector.js.map +1 -0
  230. package/dist/react/hooks/useStorage.d.ts +39 -0
  231. package/dist/react/hooks/useStorage.d.ts.map +1 -0
  232. package/dist/react/hooks/useStorage.js +78 -0
  233. package/dist/react/hooks/useStorage.js.map +1 -0
  234. package/dist/react/hooks/useStorageSubscribe.d.ts +16 -0
  235. package/dist/react/hooks/useStorageSubscribe.d.ts.map +1 -0
  236. package/dist/react/hooks/useStorageSubscribe.js +55 -0
  237. package/dist/react/hooks/useStorageSubscribe.js.map +1 -0
  238. package/dist/react/index.d.ts +3 -0
  239. package/dist/react/index.d.ts.map +1 -0
  240. package/dist/react/index.js +7 -0
  241. package/dist/react/index.js.map +1 -0
  242. package/dist/react/utils/awaitSynapse.d.ts +34 -0
  243. package/dist/react/utils/awaitSynapse.d.ts.map +1 -0
  244. package/dist/react/utils/awaitSynapse.js +87 -0
  245. package/dist/react/utils/awaitSynapse.js.map +1 -0
  246. package/dist/react/utils/createSynapseCtx.d.ts +33 -0
  247. package/dist/react/utils/createSynapseCtx.d.ts.map +1 -0
  248. package/dist/react/utils/createSynapseCtx.js +139 -0
  249. package/dist/react/utils/createSynapseCtx.js.map +1 -0
  250. package/dist/react/utils/index.d.ts +3 -0
  251. package/dist/react/utils/index.d.ts.map +1 -0
  252. package/dist/react/utils/index.js +9 -0
  253. package/dist/react/utils/index.js.map +1 -0
  254. package/dist/reactive/dispatcher/dispatcher.module.d.ts +216 -0
  255. package/dist/reactive/dispatcher/dispatcher.module.d.ts.map +1 -0
  256. package/dist/reactive/dispatcher/dispatcher.module.js +384 -0
  257. package/dist/reactive/dispatcher/dispatcher.module.js.map +1 -0
  258. package/dist/reactive/dispatcher/index.d.ts +4 -0
  259. package/dist/reactive/dispatcher/index.d.ts.map +1 -0
  260. package/dist/reactive/dispatcher/index.js +9 -0
  261. package/dist/reactive/dispatcher/index.js.map +1 -0
  262. package/dist/reactive/dispatcher/middlewares/index.d.ts +2 -0
  263. package/dist/reactive/dispatcher/middlewares/index.d.ts.map +1 -0
  264. package/dist/reactive/dispatcher/middlewares/index.js +5 -0
  265. package/dist/reactive/dispatcher/middlewares/index.js.map +1 -0
  266. package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts +37 -0
  267. package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts.map +1 -0
  268. package/dist/reactive/dispatcher/middlewares/logger.middleware.js +188 -0
  269. package/dist/reactive/dispatcher/middlewares/logger.middleware.js.map +1 -0
  270. package/dist/reactive/dispatcher/standalone.d.ts +112 -0
  271. package/dist/reactive/dispatcher/standalone.d.ts.map +1 -0
  272. package/dist/reactive/dispatcher/standalone.js +142 -0
  273. package/dist/reactive/dispatcher/standalone.js.map +1 -0
  274. package/dist/reactive/effects/effects.module.d.ts +225 -0
  275. package/dist/reactive/effects/effects.module.d.ts.map +1 -0
  276. package/dist/reactive/effects/effects.module.js +356 -0
  277. package/dist/reactive/effects/effects.module.js.map +1 -0
  278. package/dist/reactive/effects/index.d.ts +4 -0
  279. package/dist/reactive/effects/index.d.ts.map +1 -0
  280. package/dist/reactive/effects/index.js +11 -0
  281. package/dist/reactive/effects/index.js.map +1 -0
  282. package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts +12 -0
  283. package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts.map +1 -0
  284. package/dist/reactive/effects/utils/chunkRequestConsistent.js +25 -0
  285. package/dist/reactive/effects/utils/chunkRequestConsistent.js.map +1 -0
  286. package/dist/reactive/effects/utils/chunkRequestParallel.d.ts +12 -0
  287. package/dist/reactive/effects/utils/chunkRequestParallel.d.ts.map +1 -0
  288. package/dist/reactive/effects/utils/chunkRequestParallel.js +22 -0
  289. package/dist/reactive/effects/utils/chunkRequestParallel.js.map +1 -0
  290. package/dist/reactive/effects/utils/fromRequest.d.ts +40 -0
  291. package/dist/reactive/effects/utils/fromRequest.d.ts.map +1 -0
  292. package/dist/reactive/effects/utils/fromRequest.js +64 -0
  293. package/dist/reactive/effects/utils/fromRequest.js.map +1 -0
  294. package/dist/reactive/effects/utils/index.d.ts +5 -0
  295. package/dist/reactive/effects/utils/index.d.ts.map +1 -0
  296. package/dist/reactive/effects/utils/index.js +11 -0
  297. package/dist/reactive/effects/utils/index.js.map +1 -0
  298. package/dist/reactive/effects/utils/toObservable.d.ts +23 -0
  299. package/dist/reactive/effects/utils/toObservable.d.ts.map +1 -0
  300. package/dist/reactive/effects/utils/toObservable.js +39 -0
  301. package/dist/reactive/effects/utils/toObservable.js.map +1 -0
  302. package/dist/reactive/index.d.ts +3 -0
  303. package/dist/reactive/index.d.ts.map +1 -0
  304. package/dist/reactive/index.js +7 -0
  305. package/dist/reactive/index.js.map +1 -0
  306. package/dist/utils/createEventBus.d.ts +87 -0
  307. package/dist/utils/createEventBus.d.ts.map +1 -0
  308. package/dist/utils/createEventBus.js +215 -0
  309. package/dist/utils/createEventBus.js.map +1 -0
  310. package/dist/utils/createSynapse/createSynapse.d.ts +9 -0
  311. package/dist/utils/createSynapse/createSynapse.d.ts.map +1 -0
  312. package/dist/utils/createSynapse/createSynapse.js +103 -0
  313. package/dist/utils/createSynapse/createSynapse.js.map +1 -0
  314. package/dist/utils/createSynapse/index.d.ts +3 -0
  315. package/dist/utils/createSynapse/index.d.ts.map +1 -0
  316. package/dist/utils/createSynapse/index.js +6 -0
  317. package/dist/utils/createSynapse/index.js.map +1 -0
  318. package/dist/utils/createSynapse/types.d.ts +93 -0
  319. package/dist/utils/createSynapse/types.d.ts.map +1 -0
  320. package/dist/utils/createSynapse/types.js +6 -0
  321. package/dist/utils/createSynapse/types.js.map +1 -0
  322. package/dist/utils/createSynapse/validate.d.ts +2 -0
  323. package/dist/utils/createSynapse/validate.d.ts.map +1 -0
  324. package/dist/utils/createSynapse/validate.js +76 -0
  325. package/dist/utils/createSynapse/validate.js.map +1 -0
  326. package/dist/utils/createSynapse/waitForDependencies.d.ts +3 -0
  327. package/dist/utils/createSynapse/waitForDependencies.d.ts.map +1 -0
  328. package/dist/utils/createSynapse/waitForDependencies.js +40 -0
  329. package/dist/utils/createSynapse/waitForDependencies.js.map +1 -0
  330. package/dist/utils/createSynapseAwaiter.d.ts +46 -0
  331. package/dist/utils/createSynapseAwaiter.d.ts.map +1 -0
  332. package/dist/utils/createSynapseAwaiter.js +102 -0
  333. package/dist/utils/createSynapseAwaiter.js.map +1 -0
  334. package/dist/utils/index.d.ts +4 -0
  335. package/dist/utils/index.d.ts.map +1 -0
  336. package/dist/utils/index.js +12 -0
  337. package/dist/utils/index.js.map +1 -0
  338. package/package.json +17 -21
  339. package/dist/api.d.ts +0 -365
  340. package/dist/api.js +0 -1
  341. package/dist/core.d.ts +0 -106
  342. package/dist/core.js +0 -1
  343. package/dist/createSynapse-vkfKjRob.d.ts +0 -97
  344. package/dist/dispatcher.module-BOsMHbD5.d.ts +0 -360
  345. package/dist/react.d.ts +0 -119
  346. package/dist/react.js +0 -1
  347. package/dist/reactive.d.ts +0 -35
  348. package/dist/reactive.js +0 -1
  349. package/dist/storage.interface-BA_ktyDz.d.ts +0 -591
  350. package/dist/utils.d.ts +0 -139
  351. package/dist/utils.js +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Synapse Storage
2
2
 
3
- > **🇺🇸 English** | [🇷🇺 Русский](./docs/ru/README.md) | [📝 ChangeLog](./CHANGELOG.md)
3
+ > **🇺🇸 English** | [📝 ChangeLog](./CHANGELOG.md)
4
4
 
5
5
  State management toolkit + API client
6
6
 
@@ -9,36 +9,37 @@ State management toolkit + API client
9
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.typescriptlang.org/)
10
10
  [![RxJS Version](https://img.shields.io/badge/RxJS-%5E7.8.2-red?logo=reactivex)](https://rxjs.dev/)
11
11
 
12
- ## Key Features
13
-
14
- - 🚀 **Framework Agnostic** - You can use Synapse with any framework or independently
15
- - 💾 **Various Storage Adapters** - Memory, LocalStorage, IndexedDB
16
- - 🧮 **Different Ways to Access Data** - Computed values with memoization
17
- - Ability to create Redux-style computed selectors
18
- - Ability to directly subscribe to specific properties in storage
19
- - Ability to subscribe to reactive state
20
- - 🌐 **API Client Creation** - HTTP client with caching capabilities (Similar to RTK Query)
21
- - ⚛️ **React** - Several convenient hooks for React
22
- - **RxJS** - Ability to create Redux-Observable style effects
23
- - ⚙️ **Custom Middleware Support** - Ability to extend storage functionality with custom middlewares
24
- - 🔌 **Custom Plugin Support** - Ability to extend storage functionality with custom plugins
12
+ ## Key Features
13
+
14
+ - **Framework Agnostic** works with any framework or standalone
15
+ - **Sync & Async Storage** Memory/LocalStorage (fully synchronous) and IndexedDB (async) with type-safe separation
16
+ - **Selectors** memoized computed values with dependency tracking (like Reselect)
17
+ - **Subscriptions** — subscribe to nested paths via selector functions
18
+ - **Immer-like Updates** mutate state directly inside `update()` callbacks
19
+ - **API Client** HTTP client with caching, tags, and invalidation (like RTK Query)
20
+ - **React Integration** hooks built on `useSyncExternalStore` (Concurrent Mode safe)
21
+ - **RxJS Reactive** — Redux-Observable style effects, dispatchers, and watchers
22
+ - **Middleware & Plugins** separate sync/async systems for extending storage behavior
23
+ - **Singleton Support** shared storage instances across components with merge strategies
24
+ - **EventBus** decoupled inter-module communication with wildcards and history
25
+ - **Cross-tab Sync** — BroadcastChannel middleware for multi-tab state synchronization
25
26
 
26
27
  ---
28
+
27
29
  ## Author
28
30
 
29
31
  **Vladislav** — Senior Frontend Developer (React, TypeScript)
30
32
 
31
- > ### 🔎 Currently looking for new career opportunities!
32
- >
33
- > [GitHub](https://github.com/Vlad92msk/) | [LinkedIn](https://www.linkedin.com/in/vlad-firsov/)
33
+ [GitHub](https://github.com/Vlad92msk/) | [LinkedIn](https://www.linkedin.com/in/vlad-firsov/)
34
34
 
35
35
  ---
36
36
  *PS: Not recommended for production use yet as I develop this in my free time.
37
37
  The library works in general, but I can provide guarantees only after full integration into my pet project - Social Network.
38
38
  This won't happen before changing my current workplace and country of residence*
39
+
39
40
  ---
40
41
 
41
- ## 📦 Installation
42
+ ## Installation
42
43
 
43
44
  ```bash
44
45
  npm install synapse-storage
@@ -48,144 +49,700 @@ npm install synapse-storage
48
49
  # For reactive capabilities
49
50
  npm install rxjs
50
51
 
51
- # For React integration
52
+ # For React integration
52
53
  npm install react react-dom
53
-
54
- # All at once for full functionality
55
- npm install synapse-storage rxjs react react-dom
56
54
  ```
57
55
 
58
56
  | Module | Description | Dependencies |
59
57
  |--------|-------------|--------------|
60
- | `synapse-storage/core` | base | - |
61
- | `synapse-storage/react` | React | React 18+ |
62
- | `synapse-storage/reactive` | RxJS | RxJS 7.8.2+ |
63
- | `synapse-storage/api` | HTTP client | - |
64
- | `synapse-storage/utils` | Utils | - |
58
+ | `synapse-storage/core` | Storage, selectors, middleware, plugins | |
59
+ | `synapse-storage/react` | React hooks and context utilities | React 18+ |
60
+ | `synapse-storage/reactive` | Dispatcher, effects, watchers | RxJS 7.8.2+ |
61
+ | `synapse-storage/api` | HTTP client with caching | |
62
+ | `synapse-storage/utils` | createSynapse, EventBus, awaiter | |
63
+
64
+ > Import only the modules you need — each works independently.
65
65
 
66
- > **💡 Tip:** Import only the modules you need for optimal bundle size
66
+ ### tsconfig.json
67
67
 
68
- ### tsconfig.json:
69
68
  ```json
70
69
  {
71
70
  "compilerOptions": {
72
71
  "target": "ES2022",
73
- "module": "ES2022",
72
+ "module": "ES2022",
74
73
  "moduleResolution": "bundler"
75
74
  }
76
75
  }
77
76
  ```
78
77
 
79
- ## 📚 Documentation
78
+ ---
80
79
 
81
- - [📖 Main](./README.md)
82
- - [🚀 Basic Usage](./docs/en/basic-usage.md)
83
- - [🧮 Redux-style Computed Selectors](./docs/en/redux-selectors.md)
84
- - [⚙️ Middlewares](./docs/en/middlewares.md)
85
- - [🌐 API Client](./docs/en/api-client.md)
86
- - ⚡ Reactive Approach
87
- - [⚡ Creating Dispatcher](./docs/en/create-dispatcher.md)
88
- - [⚡ Creating Effects](./docs/en/create-effects.md)
89
- - [⚡ Creating Effects Module](./docs/en/create-effects-module.md)
90
- - [🛠️ createSynapse Utility](./docs/en/create-synapse.md)
91
- - [🔌 Creating Custom Plugins](./docs/en/custom-plugins.md)
92
- - [⚙️ Creating Custom Middlewares](./docs/en/custom-middlewares.md)
93
- - [📋 Additional](./docs/en/additional.md)
80
+ ## Quick Start
94
81
 
95
- ## 🎯 Examples
82
+ ```typescript
83
+ import { MemoryStorage } from 'synapse-storage/core'
96
84
 
97
- - [GitHub](https://github.com/Vlad92msk/synapse-examples)
98
- - [YouTube](https://www.youtube.com/channel/UCGENI_i4qmBkPp98P2HvvGw)
85
+ const storage = new MemoryStorage({
86
+ name: 'counter',
87
+ initialState: { count: 0, user: { name: 'Anonymous' } },
88
+ })
89
+ await storage.initialize()
90
+
91
+ // Read
92
+ storage.getState() // { count: 0, user: { name: 'Anonymous' } }
93
+ storage.get('count') // 0
94
+
95
+ // Write
96
+ storage.set('count', 1)
97
+
98
+ // Immer-like update (multiple mutations = one notification)
99
+ storage.update((state) => {
100
+ state.count += 1
101
+ state.user.name = 'Alice'
102
+ })
103
+
104
+ // Subscribe to nested path
105
+ const unsub = storage.subscribe(
106
+ (s) => s.user.name,
107
+ (name) => console.log('Name changed:', name)
108
+ )
109
+
110
+ // Reset to initialState
111
+ storage.reset()
112
+ ```
99
113
 
100
114
  ---
101
115
 
102
- ## 📊 Why Synapse Storage?
116
+ ## Storage Types
103
117
 
104
- **One library instead of many** - Synapse combines functionality that usually requires multiple dependencies:
118
+ Synapse has two storage categories with **type-safe separation**:
105
119
 
106
- | What you get | Traditional approach | Synapse Storage |
107
- |--------------|---------------------|---------|
108
- | **State Management** | Redux + RTK (~45KB) | ✅ |
109
- | **HTTP Client + Caching** | React Query (~39KB) | ✅|
110
- | **Reactive Effects** | Redux-Observable (~25KB) | ✅|
111
- | **Storage Adapters** | Custom solutions | ✅|
112
- | **React Integration** | Custom hooks | ✅|
113
- | **Computed Selectors** | Reselect (~5KB) | ✅|
114
- | **Middleware System** | Custom implementation | ✅|
115
- | **Plugin Architecture** | Custom implementation | ✅|
120
+ ### Sync Storage (MemoryStorage, LocalStorage)
116
121
 
117
- ### Bundle Size Comparison
122
+ All operations are synchronous — `get()`, `set()`, `update()`, `getState()` return values directly.
118
123
 
119
124
  ```typescript
120
- // Traditional stack
121
- import { configureStore } from '@reduxjs/toolkit' // ~45KB
122
- import { createApi } from '@reduxjs/toolkit/query' // included in RTK
123
- import { QueryClient } from '@tanstack/react-query' // ~39KB
124
- import { createEpicMiddleware } from 'redux-observable' // ~25KB
125
- // Total: ~109KB + custom implementations
125
+ import { MemoryStorage, LocalStorage } from 'synapse-storage/core'
126
126
 
127
- // Synapse Storage
128
- import { createSynapse } from 'synapse-storage' // ~171KB
129
- // Total: 171KB with ALL features included
127
+ const memory = new MemoryStorage<State>({ name: 'app', initialState })
128
+ const local = new LocalStorage<State>({ name: 'app', initialState })
129
+
130
+ await memory.initialize()
131
+ const value = memory.get('key') // T — sync
130
132
  ```
131
133
 
132
- ### Modular Usage
134
+ ### Async Storage (IndexedDBStorage)
135
+
136
+ Operations return Promises — persistent browser storage.
133
137
 
134
- Don't need everything? Import only what you use:
138
+ ```typescript
139
+ import { IndexedDBStorage } from 'synapse-storage/core'
140
+
141
+ const idb = new IndexedDBStorage<State>({
142
+ name: 'app',
143
+ initialState,
144
+ options: { dbName: 'my_app_db' },
145
+ })
146
+
147
+ await idb.initialize()
148
+ const value = await idb.get('key') // Promise<T>
149
+ ```
135
150
 
136
- | Use Case | Import | Size | Comparison |
137
- |-------------------|------------------------|------|---------------------------|
138
- | **Basic state** | `synapse-storage/core` | ~42KB | vs Redux: 45KB |
139
- | **+ HTTP client** | `+ /api` | +13KB | vs React Query: 39KB |
140
- | **+ Reactive** | `+ /reactive` | +8KB | vs Redux-Observable: 25KB |
141
- | **+ React hooks** | `+ /react` | +5KB | vs Custom hooks |
142
- | **Full package** | all modules | ~171KB |vs 109KB stack + custom |
151
+ ### getStateSync()
143
152
 
144
- > **🎯 Result:** Similar or better performance with unified API and TypeScript support out of the box
153
+ Available on **all** storage types returns the cached state synchronously, even for IndexedDB:
145
154
 
146
- ## 🧩 Modular Architecture "Like a Constructor"
155
+ ```typescript
156
+ const state = storage.getStateSync() // always sync
157
+ ```
147
158
 
148
- **Use only what you need** - each module works independently:
159
+ ### Static Factory Methods
149
160
 
150
- ### 🎯 Flexible Usage Scenarios
161
+ Every storage class has a `.create()` static method:
151
162
 
152
163
  ```typescript
153
- // 📦 Minimal project - storage only
154
- import { MemoryStorage } from 'synapse-storage/core'
164
+ const storage = MemoryStorage.create<State>({ name: 'app', initialState })
165
+ const storage = LocalStorage.create<State>({ name: 'app', initialState })
166
+ const storage = IndexedDBStorage.create<State>({ name: 'app', initialState, options: {} })
167
+ ```
155
168
 
156
- // 📦 + Add HTTP client when needed
157
- import { ApiClient } from 'synapse-storage/api'
169
+ ### StorageFactory
170
+
171
+ Universal factory with type-safe overloads:
172
+
173
+ ```typescript
174
+ import { StorageFactory } from 'synapse-storage/core'
175
+
176
+ // Typed factories
177
+ const mem = StorageFactory.createMemory<S>({ name: 'x', initialState })
178
+ const loc = StorageFactory.createLocal<S>({ name: 'x', initialState })
179
+ const idb = StorageFactory.createIndexedDB<S>({ name: 'x', initialState, options: {} })
180
+
181
+ // Universal — return type depends on `type`
182
+ const storage = StorageFactory.create<S>({
183
+ type: 'memory', // → ISyncStorage<S>
184
+ name: 'x',
185
+ initialState,
186
+ })
187
+ ```
188
+
189
+ ---
190
+
191
+ ## Reading & Writing Data
192
+
193
+ ### Reading
194
+
195
+ ```typescript
196
+ storage.get('key') // value by key
197
+ storage.getState() // full state
198
+ storage.getStateSync() // sync cache (all storage types)
199
+ storage.has('key') // boolean
200
+ storage.keys() // string[]
201
+ ```
202
+
203
+ ### Writing
204
+
205
+ ```typescript
206
+ storage.set('key', value) // set single key
207
+ storage.update((s) => { s.count++ }) // Immer-like mutations
208
+ storage.remove('key') // delete key
209
+ storage.reset() // restore initialState
210
+ storage.clear() // reset to {}
211
+ ```
212
+
213
+ > For IndexedDB, all write operations return `Promise`.
214
+
215
+ ---
216
+
217
+ ## Subscriptions
218
+
219
+ ```typescript
220
+ // Subscribe by key
221
+ const unsub = storage.subscribe('count', (newValue) => {
222
+ console.log('count:', newValue)
223
+ })
224
+
225
+ // Subscribe by selector function (nested paths)
226
+ const unsub = storage.subscribe(
227
+ (state) => state.user.name,
228
+ (name) => console.log('name:', name)
229
+ )
230
+
231
+ // Subscribe to all changes
232
+ const unsub = storage.subscribeToAll((event) => {
233
+ // event.type: 'set' | 'update' | 'remove' | 'clear' | 'reset'
234
+ // event.key, event.changedPaths
235
+ })
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Selector System
241
+
242
+ Memoized computed values with dependency tracking:
243
+
244
+ ```typescript
245
+ import { SelectorModule } from 'synapse-storage/core'
246
+
247
+ const sm = new SelectorModule(storage)
248
+
249
+ // Simple selector
250
+ const count = sm.createSelector((state) => state.count)
251
+
252
+ // With custom equality
253
+ const items = sm.createSelector(
254
+ (state) => state.items,
255
+ { equals: (a, b) => JSON.stringify(a) === JSON.stringify(b) }
256
+ )
257
+
258
+ // Dependent selector (recalculates only when deps change)
259
+ const filtered = sm.createSelector(
260
+ [items, filter],
261
+ (itemsVal, filterVal) => itemsVal.filter(i => i.type === filterVal)
262
+ )
263
+
264
+ // Usage
265
+ const value = filtered.select()
266
+ const unsub = filtered.subscribe({ notify: (value) => console.log(value) })
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Middleware System
272
+
273
+ Separate sync and async middleware for each storage type:
274
+
275
+ ```typescript
276
+ const storage = new MemoryStorage<State>({
277
+ name: 'store',
278
+ initialState,
279
+ middlewares: (getDefault) => [
280
+ // Batch rapid writes
281
+ getDefault().batching({ batchSize: 5, batchDelay: 100 }),
282
+
283
+ // Skip updates if value unchanged
284
+ getDefault().shallowCompare(),
285
+ ],
286
+ })
287
+ ```
288
+
289
+ ### Cross-tab Synchronization
290
+
291
+ ```typescript
292
+ import { syncBroadcastMiddleware } from 'synapse-storage/core'
293
+
294
+ const storage = new MemoryStorage<State>({
295
+ name: 'store',
296
+ initialState,
297
+ middlewares: () => [
298
+ syncBroadcastMiddleware({ storageName: 'store', storageType: 'memory' }),
299
+ ],
300
+ })
301
+ ```
302
+
303
+ ---
304
+
305
+ ## Plugin System
306
+
307
+ Lifecycle hooks for intercepting storage operations:
308
+
309
+ ```typescript
310
+ import { ISyncStoragePlugin, SyncStoragePluginModule } from 'synapse-storage/core'
311
+
312
+ class TimestampPlugin implements ISyncStoragePlugin {
313
+ name = 'timestamp'
314
+
315
+ async initialize() {}
316
+ async destroy() {}
317
+
318
+ onBeforeSet<T>(value: T, context): T { return value }
319
+ onAfterSet<T>(key, value: T, ctx): T { return value }
320
+ onBeforeGet(key, ctx) { return key }
321
+ onAfterGet<T>(key, value: T | undefined, ctx) { return value }
322
+ onBeforeDelete(key, ctx): boolean { return true } // false = block
323
+ onAfterDelete(key, ctx) {}
324
+ onClear(ctx) {}
325
+ }
326
+
327
+ const plugins = new SyncStoragePluginModule(undefined, undefined, 'store')
328
+ await plugins.add(new TimestampPlugin())
329
+
330
+ const storage = new MemoryStorage<State>(
331
+ { name: 'store', initialState },
332
+ plugins
333
+ )
334
+ ```
335
+
336
+ > For IndexedDB, use `IAsyncStoragePlugin` and `AsyncStoragePluginModule`.
337
+
338
+ ---
339
+
340
+ ## React Integration
341
+
342
+ Hooks are built on `useSyncExternalStore` — safe in Concurrent Mode, no tearing.
343
+
344
+ ### useCreateStorage
345
+
346
+ Returns a **discriminated union**: when `isReady: true`, `storage` is guaranteed non-null.
158
347
 
159
- // 📦 + Add reactive effects when required
160
- import { createDispatcher } from 'synapse-storage/reactive'
348
+ ```tsx
349
+ import { useCreateStorage } from 'synapse-storage/react'
161
350
 
162
- // 📦 + Add React hooks for UI
351
+ function App() {
352
+ const { storage, isReady } = useCreateStorage<State>({
353
+ type: 'memory', // 'memory' | 'localStorage' → ISyncStorage
354
+ name: 'app', // 'indexedDB' → IAsyncStorage
355
+ initialState: { count: 0 },
356
+ })
357
+
358
+ if (!isReady) return <div>Loading...</div>
359
+ // storage is ISyncStorage<State> here (not null)
360
+ }
361
+ ```
362
+
363
+ ### useStorageSubscribe
364
+
365
+ ```tsx
366
+ import { useStorageSubscribe } from 'synapse-storage/react'
367
+
368
+ function Counter() {
369
+ const count = useStorageSubscribe(storage, (s) => s.count)
370
+ const summary = useStorageSubscribe(storage, (s) => `Total: ${s.count}`)
371
+ return <div>{count} — {summary}</div>
372
+ }
373
+ ```
374
+
375
+ ### useSelector
376
+
377
+ ```tsx
163
378
  import { useSelector } from 'synapse-storage/react'
379
+
380
+ function ItemList() {
381
+ const items = useSelector(filteredItemsSelector)
382
+ return <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>
383
+ }
164
384
  ```
165
385
 
166
- ### 🔧 Or Create Your Own Implementation
386
+ ### createSynapseCtx
387
+
388
+ Context-based pattern for sharing synapse across component tree:
389
+
390
+ ```tsx
391
+ import { createSynapseCtx, useSelector } from 'synapse-storage/react'
392
+
393
+ const {
394
+ contextSynapse,
395
+ useSynapseStorage,
396
+ useSynapseSelectors,
397
+ useSynapseActions,
398
+ cleanupSynapse,
399
+ } = createSynapseCtx(storePromise, {
400
+ loadingComponent: <div>Loading...</div>,
401
+ })
402
+
403
+ const Page = contextSynapse(() => {
404
+ const selectors = useSynapseSelectors()
405
+ const actions = useSynapseActions()
406
+ const count = useSelector(selectors.count)
407
+
408
+ return <button onClick={() => actions.increment()}>Count: {count}</button>
409
+ })
410
+ ```
411
+
412
+ ### awaitSynapse
413
+
414
+ HOC and hook for waiting on synapse initialization:
415
+
416
+ ```tsx
417
+ import { awaitSynapse } from 'synapse-storage/react'
418
+
419
+ const awaiter = awaitSynapse(storePromise, {
420
+ loadingComponent: <div>Loading...</div>,
421
+ errorComponent: (error) => <div>Error: {error.message}</div>,
422
+ })
423
+
424
+ // HOC
425
+ const ReadyComponent = awaiter.withSynapseReady(MyComponent)
426
+
427
+ // Hook
428
+ function Status() {
429
+ const { isReady, isPending, isError, store } = awaiter.useSynapseReady()
430
+ if (isPending) return <div>Loading...</div>
431
+ if (isError) return <div>Error</div>
432
+ return <div>Ready</div>
433
+ }
434
+
435
+ // Programmatic (also works outside React)
436
+ awaiter.isReady() // boolean
437
+ awaiter.getStatus() // 'pending' | 'ready' | 'error'
438
+ await awaiter.waitForReady() // Promise<Store>
439
+ awaiter.onReady((store) => { /* ... */ })
440
+ ```
441
+
442
+ ---
443
+
444
+ ## Reactive Features (RxJS)
445
+
446
+ ### Dispatcher — Actions & Watchers
167
447
 
168
448
  ```typescript
169
- // Use core + your solutions
170
- import { IStorage } from 'synapse-storage/core'
449
+ import { createDispatcher, createAction, createWatcher } from 'synapse-storage/reactive'
450
+
451
+ const dispatcher = createDispatcher(
452
+ { storage },
453
+ (_storage, { createAction, createWatcher }) => {
454
+ const increment = createAction({
455
+ type: 'increment',
456
+ action: () => storage.update((s) => { s.count += 1 }),
457
+ })
458
+
459
+ const setName = createAction({
460
+ type: 'setName',
461
+ action: (name: string) => {
462
+ storage.set('name', name)
463
+ return name
464
+ },
465
+ })
466
+
467
+ const watchCount = createWatcher({
468
+ type: 'watchCount',
469
+ selector: (state) => state.count,
470
+ shouldTrigger: (prev, curr) => prev !== curr,
471
+ notifyAfterSubscribe: true,
472
+ })
473
+
474
+ return { increment, setName, watchCount }
475
+ }
476
+ )
477
+
478
+ // Dispatch
479
+ dispatcher.dispatch.increment()
480
+ dispatcher.dispatch.setName('Alice')
171
481
 
172
- // Implement your HTTP client
173
- class MyApiClient { /* your logic */ }
482
+ // Watch (RxJS Observable)
483
+ dispatcher.watchers.watchCount().subscribe((action) => {
484
+ console.log('count:', action.payload)
485
+ })
174
486
 
175
- // Implement your React hooks
176
- const useMyCustomHook = () => { /* your logic */ }
487
+ // Action stream
488
+ dispatcher.actions.subscribe((action) => {
489
+ console.log(action.type, action.payload)
490
+ })
177
491
 
178
- // Combine as convenient!
492
+ dispatcher.destroy()
179
493
  ```
180
494
 
181
- ### 🎨 Constructor Approach Benefits
495
+ ### Effects
182
496
 
183
- - **🚀 Quick Start** - begin with core, add modules as project grows
184
- - **📦 Optimal Bundle** - don't pay for unused functionality
185
- - **🔄 Flexibility** - replace any module with your implementation
186
- - **🛠️ Compatibility** - modules work independently but integrate perfectly
187
- - **📈 Scalability** - from simple state to full-featured architecture
497
+ ```typescript
498
+ import { createEffect, ofType } from 'synapse-storage/reactive'
499
+ import { debounceTime, switchMap, tap } from 'rxjs/operators'
500
+
501
+ createEffect((action$, state$, { dispatcher }) =>
502
+ action$.pipe(
503
+ ofType(dispatcher.dispatch.search),
504
+ debounceTime(400),
505
+ switchMap((action) =>
506
+ fetchResults(action.payload).pipe(
507
+ tap((results) => dispatcher.dispatch.searchSuccess(results))
508
+ )
509
+ )
510
+ )
511
+ )
512
+ ```
513
+
514
+ ---
515
+
516
+ ## createSynapse
188
517
 
189
- > **💡 Evolution Example:** Started with MemoryStorage added ApiClient → connected reactive effects → integrated React hooks. **Each step is optional!**
518
+ High-level utility that wires storage + selectors + dispatcher + effects together:
519
+
520
+ ```typescript
521
+ import { createSynapse } from 'synapse-storage/utils'
522
+
523
+ const storePromise = createSynapse({
524
+ storage: new MemoryStorage<State>({ name: 'app', initialState }),
525
+
526
+ createSelectorsFn: (sm) => ({
527
+ count: sm.createSelector((s) => s.count),
528
+ doubled: sm.createSelector(
529
+ [count],
530
+ (c) => c * 2
531
+ ),
532
+ }),
533
+
534
+ createDispatcherFn: (storage) =>
535
+ createDispatcher({ storage }, (_s, { createAction, createWatcher }) => ({
536
+ increment: createAction({
537
+ type: 'increment',
538
+ action: () => storage.update((s) => { s.count += 1 }),
539
+ }),
540
+ watchCount: createWatcher({
541
+ type: 'watchCount',
542
+ selector: (s) => s.count,
543
+ }),
544
+ })),
545
+
546
+ effects: [
547
+ createEffect((action$, state$, { dispatcher }) =>
548
+ action$.pipe(/* ... */)
549
+ ),
550
+ ],
551
+ })
552
+
553
+ const store = await storePromise
554
+
555
+ store.storage // ISyncStorage<State>
556
+ store.selectors // { count, doubled }
557
+ store.actions // { increment, ... }
558
+ store.dispatcher // Dispatcher
559
+ store.state$ // Observable<State> (when effects are used)
560
+ store.destroy() // cleanup everything
561
+ ```
562
+
563
+ ### Dependencies
564
+
565
+ ```typescript
566
+ const authStore = createSynapse({ /* ... */ })
567
+
568
+ const settingsStore = createSynapse({
569
+ dependencies: [authStore],
570
+ dependencyTimeout: 5000,
571
+
572
+ createStorageFn: async () => {
573
+ const auth = await authStore
574
+ const userId = auth.storage.getStateSync().userId
575
+ const storage = new MemoryStorage({ name: 'settings', initialState: { userId } })
576
+ await storage.initialize()
577
+ return storage
578
+ },
579
+ })
580
+ ```
581
+
582
+ ---
583
+
584
+ ## API Client
585
+
586
+ HTTP client with typed endpoints, caching, and tag-based invalidation:
587
+
588
+ ```typescript
589
+ import { ApiClient } from 'synapse-storage/api'
590
+ import { MemoryStorage } from 'synapse-storage/core'
591
+
592
+ const cacheStorage = new MemoryStorage<Record<string, any>>({
593
+ name: 'api-cache',
594
+ initialState: {},
595
+ })
596
+
597
+ const api = new ApiClient({
598
+ storage: cacheStorage,
599
+ baseQuery: {
600
+ baseUrl: 'https://api.example.com',
601
+ timeout: 10000,
602
+ prepareHeaders: async (headers, context) => {
603
+ headers.set('Authorization', `Bearer ${token}`)
604
+ return headers
605
+ },
606
+ },
607
+ cache: {
608
+ ttl: 60000,
609
+ cleanup: { enabled: true, interval: 120000 },
610
+ invalidateOnError: true,
611
+ },
612
+ endpoints: async (create) => ({
613
+ getUsers: create<{ limit?: number }, UsersResponse>({
614
+ request: (params) => ({
615
+ path: '/users',
616
+ method: 'GET',
617
+ query: params,
618
+ }),
619
+ cache: { ttl: 120000 },
620
+ tags: ['users'],
621
+ }),
622
+ createUser: create<CreateUserInput, User>({
623
+ request: (params) => ({
624
+ path: '/users',
625
+ method: 'POST',
626
+ body: params,
627
+ }),
628
+ invalidatesTags: ['users'],
629
+ cache: false,
630
+ }),
631
+ }),
632
+ })
633
+
634
+ await cacheStorage.initialize()
635
+ await api.init()
636
+
637
+ // Simple request
638
+ const result = await api.request('getUsers', { limit: 10 })
639
+ if (result.ok) console.log(result.data, result.fromCache)
640
+
641
+ // Endpoint-level subscription
642
+ const endpoints = api.getEndpoints()
643
+ const req = endpoints.getUsers.request({ limit: 10 })
644
+
645
+ req.subscribe((state) => {
646
+ // state.status: 'idle' | 'loading' | 'success' | 'error'
647
+ // state.data, state.error, state.fromCache
648
+ })
649
+
650
+ const result = await req.wait()
651
+ req.abort()
652
+ ```
653
+
654
+ ---
655
+
656
+ ## EventBus
657
+
658
+ Decoupled communication between modules:
659
+
660
+ ```typescript
661
+ import { createEventBus } from 'synapse-storage/utils'
662
+
663
+ const eventBus = await createEventBus({
664
+ name: 'app-events',
665
+ autoCleanup: true,
666
+ maxEvents: 1000,
667
+ })
668
+
669
+ // Publish
670
+ await eventBus.actions.publish({
671
+ event: 'USER_UPDATED',
672
+ data: { userId: 123 },
673
+ metadata: { priority: 'high', ttl: 60000 },
674
+ })
675
+
676
+ // Subscribe (supports wildcards)
677
+ const { unsubscribe } = await eventBus.actions.subscribe({
678
+ eventPattern: 'USER_*',
679
+ handler: (data, event) => console.log(event.event, data),
680
+ })
681
+
682
+ // History
683
+ const history = await eventBus.actions.getEventHistory({
684
+ eventType: 'USER_UPDATED',
685
+ limit: 10,
686
+ })
687
+
688
+ await eventBus.destroy()
689
+ ```
690
+
691
+ ---
692
+
693
+ ## Singleton Pattern
694
+
695
+ Share storage instances across components:
696
+
697
+ ```typescript
698
+ import { MemoryStorage, ConfigMergeStrategy } from 'synapse-storage/core'
699
+
700
+ // Component A
701
+ const storage1 = new MemoryStorage({
702
+ name: 'shared',
703
+ singleton: {
704
+ enabled: true,
705
+ mergeStrategy: ConfigMergeStrategy.FIRST_WINS,
706
+ },
707
+ initialState: { count: 0 },
708
+ })
709
+
710
+ // Component B — gets the same instance
711
+ const storage2 = new MemoryStorage({
712
+ name: 'shared',
713
+ singleton: { enabled: true },
714
+ initialState: { count: 99 }, // ignored (FIRST_WINS)
715
+ })
716
+
717
+ storage1 === storage2 // true
718
+ ```
719
+
720
+ Merge strategies: `FIRST_WINS`, `DEEP_MERGE`, `OVERRIDE`, `WARN_AND_USE_FIRST`, `STRICT` (throws).
190
721
 
191
722
  ---
723
+
724
+ ## Storage Lifecycle
725
+
726
+ ```typescript
727
+ await storage.initialize()
728
+ await storage.waitForReady()
729
+
730
+ storage.initStatus // { status: 'ready' | 'loading' | 'error' | 'idle' }
731
+
732
+ const unsub = storage.onStatusChange((status) => console.log(status))
733
+
734
+ await storage.destroy()
735
+ ```
736
+
737
+ ---
738
+
739
+ ## Examples
740
+
741
+ - [GitHub Examples](https://github.com/Vlad92msk/synapse-examples)
742
+ - [YouTube](https://www.youtube.com/channel/UCGENI_i4qmBkPp93P2HvvGw)
743
+
744
+ ---
745
+
746
+ ## License
747
+
748
+ MIT