@cendarsoss/pusher-js 8.4.11

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 (425) hide show
  1. package/.editorconfig +14 -0
  2. package/.github/ISSUE_TEMPLATE.md +11 -0
  3. package/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  4. package/.github/dependabot.yml +14 -0
  5. package/.github/stale.yml +26 -0
  6. package/.github/workflows/release.yml +112 -0
  7. package/.github/workflows/release_pr.yml +43 -0
  8. package/.github/workflows/run-tests.yml +62 -0
  9. package/.gitmodules +3 -0
  10. package/.prettierrc +2 -0
  11. package/CHANGELOG.md +928 -0
  12. package/DELTA_COMPRESSION.md +365 -0
  13. package/DELTA_USAGE.md +179 -0
  14. package/IMPLEMENTATION_SUMMARY.md +261 -0
  15. package/IMPORT_GUIDE.md +638 -0
  16. package/LIBRARY_STRUCTURE_ANALYSIS.md +940 -0
  17. package/LICENCE +19 -0
  18. package/Makefile +14 -0
  19. package/README.md +709 -0
  20. package/TAG_FILTERING_CLIENT.md +471 -0
  21. package/bower.json +19 -0
  22. package/bun.lock +2695 -0
  23. package/dist/node/filter.js +252 -0
  24. package/dist/node/filter.js.map +1 -0
  25. package/dist/node/pusher.js +4434 -0
  26. package/dist/node/pusher.js.map +1 -0
  27. package/dist/web/filter.mjs +252 -0
  28. package/dist/web/filter.mjs.map +1 -0
  29. package/dist/web/pusher.mjs +5889 -0
  30. package/dist/web/pusher.mjs.map +1 -0
  31. package/examples/delta-compression-example.html +372 -0
  32. package/examples/delta-seamless-example.html +185 -0
  33. package/index.d.ts +36 -0
  34. package/integration_tests_server/index.js +176 -0
  35. package/integration_tests_server/package-lock.json +1177 -0
  36. package/integration_tests_server/package.json +15 -0
  37. package/interactive/.env +16 -0
  38. package/interactive/CONFLATION_TEST.md +73 -0
  39. package/interactive/DELTA_COMPRESSION_TESTING.md +262 -0
  40. package/interactive/bun.lock +208 -0
  41. package/interactive/package-lock.json +1075 -0
  42. package/interactive/package.json +32 -0
  43. package/interactive/public/app.js +1363 -0
  44. package/interactive/public/bundle-entry.js +14 -0
  45. package/interactive/public/conflation-test.html +508 -0
  46. package/interactive/public/conflation-test.js +785 -0
  47. package/interactive/public/delta-compression.js +1090 -0
  48. package/interactive/public/dist/bundle.js +5857 -0
  49. package/interactive/public/index.html +392 -0
  50. package/interactive/public/main.js +20 -0
  51. package/interactive/public/style.css +823 -0
  52. package/interactive/server.js +246 -0
  53. package/interactive/test-bundle.html +89 -0
  54. package/interactive/test-delta.js +146 -0
  55. package/node.js +1 -0
  56. package/package.json +94 -0
  57. package/pusher-with-encryption/index.js +1 -0
  58. package/react-native/index.d.ts +29 -0
  59. package/react-native/index.js +1 -0
  60. package/spec/config/jasmine/helpers/reporter.js +14 -0
  61. package/spec/config/jasmine/integration.json +13 -0
  62. package/spec/config/jasmine/unit.json +13 -0
  63. package/spec/config/jasmine/webpack.integration.js +33 -0
  64. package/spec/config/jasmine/webpack.unit.js +30 -0
  65. package/spec/config/karma/available_browsers.json +4957 -0
  66. package/spec/config/karma/config.ci.js +25 -0
  67. package/spec/config/karma/config.common.js +50 -0
  68. package/spec/config/karma/config.integration.js +26 -0
  69. package/spec/config/karma/config.unit.js +10 -0
  70. package/spec/config/karma/config.worker.js +34 -0
  71. package/spec/config/karma/integration.js +24 -0
  72. package/spec/config/karma/unit.js +20 -0
  73. package/spec/javascripts/helpers/mocks.js +274 -0
  74. package/spec/javascripts/helpers/node/integration.js +33 -0
  75. package/spec/javascripts/helpers/node/mock-dom-dependencies.ts +1 -0
  76. package/spec/javascripts/helpers/pusher_integration.js +1 -0
  77. package/spec/javascripts/helpers/pusher_integration_class.ts +12 -0
  78. package/spec/javascripts/helpers/timers/promises.js +9 -0
  79. package/spec/javascripts/helpers/waitsFor.js +37 -0
  80. package/spec/javascripts/helpers/web/integration.js +44 -0
  81. package/spec/javascripts/helpers/worker/mock-dom-dependencies.js +1 -0
  82. package/spec/javascripts/integration/core/cluster_config_spec.js +153 -0
  83. package/spec/javascripts/integration/core/falling_back_spec.js +195 -0
  84. package/spec/javascripts/integration/core/pusher_spec/index.js +68 -0
  85. package/spec/javascripts/integration/core/pusher_spec/test_builder.js +715 -0
  86. package/spec/javascripts/integration/core/timeout_configuration_spec.js +200 -0
  87. package/spec/javascripts/integration/core/transport_lists_spec.js +103 -0
  88. package/spec/javascripts/integration/index.node.js +12 -0
  89. package/spec/javascripts/integration/index.web.js +63 -0
  90. package/spec/javascripts/integration/index.worker.js +13 -0
  91. package/spec/javascripts/integration/web/dom/jsonp_spec.js +97 -0
  92. package/spec/javascripts/integration/web/dom/script_request_spec.js +90 -0
  93. package/spec/javascripts/polyfills/index.js +105 -0
  94. package/spec/javascripts/unit/core/channels/channel_spec.js +355 -0
  95. package/spec/javascripts/unit/core/channels/channels_spec.js +94 -0
  96. package/spec/javascripts/unit/core/channels/encrypted_channel_spec.js +343 -0
  97. package/spec/javascripts/unit/core/channels/presence_channel_spec.js +553 -0
  98. package/spec/javascripts/unit/core/channels/private_channel_spec.js +182 -0
  99. package/spec/javascripts/unit/core/config_spec.js +507 -0
  100. package/spec/javascripts/unit/core/connection/connection_manager_spec.js +656 -0
  101. package/spec/javascripts/unit/core/connection/connection_spec.js +286 -0
  102. package/spec/javascripts/unit/core/connection/handshake_spec.js +160 -0
  103. package/spec/javascripts/unit/core/connection/protocol_spec.js +420 -0
  104. package/spec/javascripts/unit/core/defaults_spec.js +26 -0
  105. package/spec/javascripts/unit/core/events_dispatcher_spec.js +385 -0
  106. package/spec/javascripts/unit/core/http/http_polling_socket_spec.js +60 -0
  107. package/spec/javascripts/unit/core/http/http_request_spec.js +185 -0
  108. package/spec/javascripts/unit/core/http/http_socket_spec.js +370 -0
  109. package/spec/javascripts/unit/core/http/http_streaming_socket_spec.js +56 -0
  110. package/spec/javascripts/unit/core/http/http_xhr_request_spec.js +164 -0
  111. package/spec/javascripts/unit/core/logger_spec.js +133 -0
  112. package/spec/javascripts/unit/core/pusher_spec.js +613 -0
  113. package/spec/javascripts/unit/core/pusher_with_encryption_spec.js +18 -0
  114. package/spec/javascripts/unit/core/strategies/best_connected_ever_strategy_spec.js +104 -0
  115. package/spec/javascripts/unit/core/strategies/delayed_strategy_spec.js +95 -0
  116. package/spec/javascripts/unit/core/strategies/first_connected_strategy_spec.js +68 -0
  117. package/spec/javascripts/unit/core/strategies/if_strategy_spec.js +165 -0
  118. package/spec/javascripts/unit/core/strategies/sequential_strategy_spec.js +213 -0
  119. package/spec/javascripts/unit/core/strategies/transport_strategy_spec.js +250 -0
  120. package/spec/javascripts/unit/core/strategies/websocket_prioritized_cached_strategy_spec.js +400 -0
  121. package/spec/javascripts/unit/core/timeline/timeline_spec.js +153 -0
  122. package/spec/javascripts/unit/core/transports/assistant_to_the_transport_manager_spec.js +223 -0
  123. package/spec/javascripts/unit/core/transports/hosts_and_ports_spec.js +85 -0
  124. package/spec/javascripts/unit/core/transports/transport_connection_spec.js +585 -0
  125. package/spec/javascripts/unit/core/transports/transport_manager_spec.js +64 -0
  126. package/spec/javascripts/unit/core/user_spec.js +303 -0
  127. package/spec/javascripts/unit/core/utils/periodic_timer_spec.js +74 -0
  128. package/spec/javascripts/unit/core/utils/timers_spec.js +157 -0
  129. package/spec/javascripts/unit/core/utils/url_store_spec.js +14 -0
  130. package/spec/javascripts/unit/core/watchlist_spec.js +48 -0
  131. package/spec/javascripts/unit/core_with_runtime/auth/channel_authorizer_spec.js +137 -0
  132. package/spec/javascripts/unit/core_with_runtime/auth/deprecated_channel_authorizer_spec.js +48 -0
  133. package/spec/javascripts/unit/core_with_runtime/auth/user_authorizer_spec.js +128 -0
  134. package/spec/javascripts/unit/core_with_runtime/readme.md +5 -0
  135. package/spec/javascripts/unit/index.node.js +11 -0
  136. package/spec/javascripts/unit/index.web.js +12 -0
  137. package/spec/javascripts/unit/index.worker.js +11 -0
  138. package/spec/javascripts/unit/isomorphic/transports/hosts_and_ports_spec.js +82 -0
  139. package/spec/javascripts/unit/isomorphic/transports/transports_spec.js +202 -0
  140. package/spec/javascripts/unit/node/timeline_sender_spec.js +83 -0
  141. package/spec/javascripts/unit/web/dom/dependency_loader_spec.js +249 -0
  142. package/spec/javascripts/unit/web/dom/jsonp_request_spec.js +130 -0
  143. package/spec/javascripts/unit/web/dom/script_receiver_factory_spec.js +68 -0
  144. package/spec/javascripts/unit/web/http/http_xdomain_request_spec.js +222 -0
  145. package/spec/javascripts/unit/web/pusher_authorizer_spec.js +64 -0
  146. package/spec/javascripts/unit/web/timeline/timeline_sender_spec.js +131 -0
  147. package/spec/javascripts/unit/web/transports/hosts_and_ports_spec.js +127 -0
  148. package/spec/javascripts/unit/web/transports/transports_spec.js +444 -0
  149. package/spec/javascripts/unit/worker/channel_authorizer_spec.js +156 -0
  150. package/spec/javascripts/unit/worker/timeline_sender_spec.js +76 -0
  151. package/src/core/auth/auth_transports.ts +18 -0
  152. package/src/core/auth/channel_authorizer.ts +64 -0
  153. package/src/core/auth/deprecated_channel_authorizer.ts +56 -0
  154. package/src/core/auth/options.ts +76 -0
  155. package/src/core/auth/user_authenticator.ts +62 -0
  156. package/src/core/base64.ts +49 -0
  157. package/src/core/channels/channel.ts +173 -0
  158. package/src/core/channels/channel_table.ts +7 -0
  159. package/src/core/channels/channels.ts +86 -0
  160. package/src/core/channels/encrypted_channel.ts +150 -0
  161. package/src/core/channels/filter.ts +342 -0
  162. package/src/core/channels/members.ts +80 -0
  163. package/src/core/channels/metadata.ts +5 -0
  164. package/src/core/channels/presence_channel.ts +113 -0
  165. package/src/core/channels/private_channel.ts +25 -0
  166. package/src/core/config.ts +189 -0
  167. package/src/core/connection/callbacks.ts +21 -0
  168. package/src/core/connection/connection.ts +160 -0
  169. package/src/core/connection/connection_manager.ts +371 -0
  170. package/src/core/connection/connection_manager_options.ts +14 -0
  171. package/src/core/connection/handshake/handshake_payload.ts +10 -0
  172. package/src/core/connection/handshake/index.ts +90 -0
  173. package/src/core/connection/protocol/action.ts +8 -0
  174. package/src/core/connection/protocol/message-types.ts +11 -0
  175. package/src/core/connection/protocol/protocol.ts +166 -0
  176. package/src/core/defaults.ts +66 -0
  177. package/src/core/delta/channel_state.ts +194 -0
  178. package/src/core/delta/decoders.ts +129 -0
  179. package/src/core/delta/index.ts +10 -0
  180. package/src/core/delta/manager.ts +504 -0
  181. package/src/core/delta/types.ts +60 -0
  182. package/src/core/errors.ts +69 -0
  183. package/src/core/events/callback.ts +6 -0
  184. package/src/core/events/callback_registry.ts +75 -0
  185. package/src/core/events/callback_table.ts +7 -0
  186. package/src/core/events/dispatcher.ts +84 -0
  187. package/src/core/http/ajax.ts +24 -0
  188. package/src/core/http/http_factory.ts +16 -0
  189. package/src/core/http/http_polling_socket.ts +24 -0
  190. package/src/core/http/http_request.ts +81 -0
  191. package/src/core/http/http_socket.ts +220 -0
  192. package/src/core/http/http_streaming_socket.ts +19 -0
  193. package/src/core/http/request_hooks.ts +9 -0
  194. package/src/core/http/socket_hooks.ts +11 -0
  195. package/src/core/http/state.ts +7 -0
  196. package/src/core/http/url_location.ts +6 -0
  197. package/src/core/logger.ts +66 -0
  198. package/src/core/options.ts +61 -0
  199. package/src/core/pusher-licence.js +7 -0
  200. package/src/core/pusher-with-encryption.js +1 -0
  201. package/src/core/pusher-with-encryption.ts +14 -0
  202. package/src/core/pusher.js +10 -0
  203. package/src/core/pusher.ts +412 -0
  204. package/src/core/reachability.ts +7 -0
  205. package/src/core/socket.ts +14 -0
  206. package/src/core/strategies/best_connected_ever_strategy.ts +81 -0
  207. package/src/core/strategies/delayed_strategy.ts +48 -0
  208. package/src/core/strategies/first_connected_strategy.ts +31 -0
  209. package/src/core/strategies/if_strategy.ts +34 -0
  210. package/src/core/strategies/sequential_strategy.ts +129 -0
  211. package/src/core/strategies/strategy.ts +8 -0
  212. package/src/core/strategies/strategy_builder.ts +67 -0
  213. package/src/core/strategies/strategy_options.ts +18 -0
  214. package/src/core/strategies/strategy_runner.ts +6 -0
  215. package/src/core/strategies/transport_strategy.ts +144 -0
  216. package/src/core/strategies/websocket_prioritized_cached_strategy.ts +157 -0
  217. package/src/core/timeline/level.ts +7 -0
  218. package/src/core/timeline/timeline.ts +90 -0
  219. package/src/core/timeline/timeline_sender.ts +33 -0
  220. package/src/core/timeline/timeline_transport.ts +11 -0
  221. package/src/core/transports/assistant_to_the_transport_manager.ts +104 -0
  222. package/src/core/transports/ping_delay_options.ts +7 -0
  223. package/src/core/transports/transport.ts +54 -0
  224. package/src/core/transports/transport_connection.ts +241 -0
  225. package/src/core/transports/transport_connection_options.ts +8 -0
  226. package/src/core/transports/transport_hooks.ts +16 -0
  227. package/src/core/transports/transport_manager.ts +52 -0
  228. package/src/core/transports/transports_table.ts +12 -0
  229. package/src/core/transports/url_scheme.ts +13 -0
  230. package/src/core/transports/url_schemes.ts +47 -0
  231. package/src/core/user.ts +186 -0
  232. package/src/core/util.ts +34 -0
  233. package/src/core/utils/collections.ts +353 -0
  234. package/src/core/utils/factory.ts +79 -0
  235. package/src/core/utils/flat_promise.ts +10 -0
  236. package/src/core/utils/timers/abstract_timer.ts +39 -0
  237. package/src/core/utils/timers/index.ts +39 -0
  238. package/src/core/utils/timers/scheduling.ts +11 -0
  239. package/src/core/utils/timers/timed_callback.ts +5 -0
  240. package/src/core/utils/url_store.ts +48 -0
  241. package/src/core/watchlist.ts +31 -0
  242. package/src/d.ts/constants/index.d.ts +5 -0
  243. package/src/d.ts/faye-websocket/faye-websocket.d.ts +21 -0
  244. package/src/d.ts/global/global.d.ts +1 -0
  245. package/src/d.ts/module/module.d.ts +12 -0
  246. package/src/d.ts/tweetnacl-util/index.d.ts +6 -0
  247. package/src/d.ts/window/events.d.ts +4 -0
  248. package/src/d.ts/window/sockjs.d.ts +3 -0
  249. package/src/d.ts/window/websocket.d.ts +4 -0
  250. package/src/d.ts/window/xmlhttprequest.d.ts +3 -0
  251. package/src/filter.ts +5 -0
  252. package/src/index.ts +8 -0
  253. package/src/runtimes/interface.ts +60 -0
  254. package/src/runtimes/isomorphic/auth/xhr_auth.ts +90 -0
  255. package/src/runtimes/isomorphic/default_strategy.ts +155 -0
  256. package/src/runtimes/isomorphic/http/http.ts +32 -0
  257. package/src/runtimes/isomorphic/http/http_xhr_request.ts +35 -0
  258. package/src/runtimes/isomorphic/runtime.ts +62 -0
  259. package/src/runtimes/isomorphic/timeline/xhr_timeline.ts +50 -0
  260. package/src/runtimes/isomorphic/transports/transport_connection_initializer.ts +19 -0
  261. package/src/runtimes/isomorphic/transports/transports.ts +83 -0
  262. package/src/runtimes/node/net_info.ts +10 -0
  263. package/src/runtimes/node/runtime.ts +68 -0
  264. package/src/runtimes/react-native/net_info.ts +42 -0
  265. package/src/runtimes/react-native/runtime.ts +65 -0
  266. package/src/runtimes/web/auth/jsonp_auth.ts +51 -0
  267. package/src/runtimes/web/browser.ts +24 -0
  268. package/src/runtimes/web/default_strategy.ts +201 -0
  269. package/src/runtimes/web/dom/dependencies.ts +16 -0
  270. package/src/runtimes/web/dom/dependency_loader.ts +93 -0
  271. package/src/runtimes/web/dom/json2.js +486 -0
  272. package/src/runtimes/web/dom/jsonp_request.ts +52 -0
  273. package/src/runtimes/web/dom/script_receiver.ts +8 -0
  274. package/src/runtimes/web/dom/script_receiver_factory.ts +57 -0
  275. package/src/runtimes/web/dom/script_request.ts +85 -0
  276. package/src/runtimes/web/http/http.ts +8 -0
  277. package/src/runtimes/web/http/http_xdomain_request.ts +37 -0
  278. package/src/runtimes/web/net_info.ts +50 -0
  279. package/src/runtimes/web/runtime.ts +174 -0
  280. package/src/runtimes/web/timeline/jsonp_timeline.ts +34 -0
  281. package/src/runtimes/web/transports/transport_connection_initializer.ts +39 -0
  282. package/src/runtimes/web/transports/transports.ts +67 -0
  283. package/src/runtimes/worker/auth/fetch_auth.ts +69 -0
  284. package/src/runtimes/worker/net_info.ts +10 -0
  285. package/src/runtimes/worker/runtime.ts +75 -0
  286. package/src/runtimes/worker/timeline/fetch_timeline.ts +39 -0
  287. package/tsconfig.json +18 -0
  288. package/types/spec/javascripts/helpers/node/mock-dom-dependencies.d.ts +1 -0
  289. package/types/spec/javascripts/helpers/pusher_integration_class.d.ts +4 -0
  290. package/types/src/core/auth/auth_transports.d.ts +9 -0
  291. package/types/src/core/auth/channel_authorizer.d.ts +3 -0
  292. package/types/src/core/auth/deprecated_channel_authorizer.d.ts +18 -0
  293. package/types/src/core/auth/options.d.ts +48 -0
  294. package/types/src/core/auth/user_authenticator.d.ts +3 -0
  295. package/types/src/core/base64.d.ts +1 -0
  296. package/types/src/core/channels/channel.d.ts +25 -0
  297. package/types/src/core/channels/channel_table.d.ts +5 -0
  298. package/types/src/core/channels/channels.d.ts +12 -0
  299. package/types/src/core/channels/encrypted_channel.d.ts +15 -0
  300. package/types/src/core/channels/filter.d.ts +33 -0
  301. package/types/src/core/channels/members.d.ts +14 -0
  302. package/types/src/core/channels/metadata.d.ts +4 -0
  303. package/types/src/core/channels/presence_channel.d.ts +13 -0
  304. package/types/src/core/channels/private_channel.d.ts +5 -0
  305. package/types/src/core/config.d.ts +31 -0
  306. package/types/src/core/connection/callbacks.d.ts +18 -0
  307. package/types/src/core/connection/connection.d.ts +16 -0
  308. package/types/src/core/connection/connection_manager.d.ts +50 -0
  309. package/types/src/core/connection/connection_manager_options.d.ts +11 -0
  310. package/types/src/core/connection/handshake/handshake_payload.d.ts +8 -0
  311. package/types/src/core/connection/handshake/index.d.ts +12 -0
  312. package/types/src/core/connection/protocol/action.d.ts +7 -0
  313. package/types/src/core/connection/protocol/message-types.d.ts +10 -0
  314. package/types/src/core/connection/protocol/protocol.d.ts +10 -0
  315. package/types/src/core/defaults.d.ts +26 -0
  316. package/types/src/core/delta/channel_state.d.ts +23 -0
  317. package/types/src/core/delta/decoders.d.ts +12 -0
  318. package/types/src/core/delta/index.d.ts +4 -0
  319. package/types/src/core/delta/manager.d.ts +27 -0
  320. package/types/src/core/delta/types.d.ts +50 -0
  321. package/types/src/core/errors.d.ts +28 -0
  322. package/types/src/core/events/callback.d.ts +5 -0
  323. package/types/src/core/events/callback_registry.d.ts +11 -0
  324. package/types/src/core/events/callback_table.d.ts +5 -0
  325. package/types/src/core/events/dispatcher.d.ts +14 -0
  326. package/types/src/core/http/ajax.d.ts +16 -0
  327. package/types/src/core/http/http_factory.d.ts +13 -0
  328. package/types/src/core/http/http_polling_socket.d.ts +3 -0
  329. package/types/src/core/http/http_request.d.ts +17 -0
  330. package/types/src/core/http/http_socket.d.ts +32 -0
  331. package/types/src/core/http/http_streaming_socket.d.ts +3 -0
  332. package/types/src/core/http/request_hooks.d.ts +6 -0
  333. package/types/src/core/http/socket_hooks.d.ts +8 -0
  334. package/types/src/core/http/state.d.ts +6 -0
  335. package/types/src/core/http/url_location.d.ts +5 -0
  336. package/types/src/core/logger.d.ts +11 -0
  337. package/types/src/core/options.d.ts +36 -0
  338. package/types/src/core/pusher-with-encryption.d.ts +5 -0
  339. package/types/src/core/pusher.d.ts +56 -0
  340. package/types/src/core/reachability.d.ts +5 -0
  341. package/types/src/core/socket.d.ts +12 -0
  342. package/types/src/core/strategies/best_connected_ever_strategy.d.ts +10 -0
  343. package/types/src/core/strategies/delayed_strategy.d.ts +15 -0
  344. package/types/src/core/strategies/first_connected_strategy.d.ts +8 -0
  345. package/types/src/core/strategies/if_strategy.d.ts +10 -0
  346. package/types/src/core/strategies/sequential_strategy.d.ts +16 -0
  347. package/types/src/core/strategies/strategy.d.ts +6 -0
  348. package/types/src/core/strategies/strategy_builder.d.ts +5 -0
  349. package/types/src/core/strategies/strategy_options.d.ts +16 -0
  350. package/types/src/core/strategies/strategy_runner.d.ts +5 -0
  351. package/types/src/core/strategies/transport_strategy.d.ts +15 -0
  352. package/types/src/core/strategies/websocket_prioritized_cached_strategy.d.ts +20 -0
  353. package/types/src/core/timeline/level.d.ts +6 -0
  354. package/types/src/core/timeline/timeline.d.ts +25 -0
  355. package/types/src/core/timeline/timeline_sender.d.ts +13 -0
  356. package/types/src/core/timeline/timeline_transport.d.ts +6 -0
  357. package/types/src/core/transports/assistant_to_the_transport_manager.d.ts +14 -0
  358. package/types/src/core/transports/ping_delay_options.d.ts +6 -0
  359. package/types/src/core/transports/transport.d.ts +8 -0
  360. package/types/src/core/transports/transport_connection.d.ts +35 -0
  361. package/types/src/core/transports/transport_connection_options.d.ts +6 -0
  362. package/types/src/core/transports/transport_hooks.d.ts +13 -0
  363. package/types/src/core/transports/transport_manager.d.ts +14 -0
  364. package/types/src/core/transports/transports_table.d.ts +10 -0
  365. package/types/src/core/transports/url_scheme.d.ts +11 -0
  366. package/types/src/core/transports/url_schemes.d.ts +4 -0
  367. package/types/src/core/user.d.ts +21 -0
  368. package/types/src/core/util.d.ts +8 -0
  369. package/types/src/core/utils/collections.d.ts +18 -0
  370. package/types/src/core/utils/factory.d.ts +29 -0
  371. package/types/src/core/utils/flat_promise.d.ts +6 -0
  372. package/types/src/core/utils/timers/abstract_timer.d.ts +10 -0
  373. package/types/src/core/utils/timers/index.d.ts +9 -0
  374. package/types/src/core/utils/timers/scheduling.d.ts +8 -0
  375. package/types/src/core/utils/timers/timed_callback.d.ts +4 -0
  376. package/types/src/core/utils/url_store.d.ts +4 -0
  377. package/types/src/core/watchlist.d.ts +8 -0
  378. package/types/src/runtimes/interface.d.ts +43 -0
  379. package/types/src/runtimes/isomorphic/auth/xhr_auth.d.ts +3 -0
  380. package/types/src/runtimes/isomorphic/default_strategy.d.ts +5 -0
  381. package/types/src/runtimes/isomorphic/http/http.d.ts +3 -0
  382. package/types/src/runtimes/isomorphic/http/http_xhr_request.d.ts +3 -0
  383. package/types/src/runtimes/isomorphic/runtime.d.ts +2 -0
  384. package/types/src/runtimes/isomorphic/timeline/xhr_timeline.d.ts +6 -0
  385. package/types/src/runtimes/isomorphic/transports/transport_connection_initializer.d.ts +1 -0
  386. package/types/src/runtimes/isomorphic/transports/transports.d.ts +5 -0
  387. package/types/src/runtimes/node/net_info.d.ts +6 -0
  388. package/types/src/runtimes/node/runtime.d.ts +3 -0
  389. package/types/src/runtimes/react-native/net_info.d.ts +8 -0
  390. package/types/src/runtimes/react-native/runtime.d.ts +3 -0
  391. package/types/src/runtimes/web/auth/jsonp_auth.d.ts +3 -0
  392. package/types/src/runtimes/web/browser.d.ts +19 -0
  393. package/types/src/runtimes/web/default_strategy.d.ts +5 -0
  394. package/types/src/runtimes/web/dom/dependencies.d.ts +4 -0
  395. package/types/src/runtimes/web/dom/dependency_loader.d.ts +10 -0
  396. package/types/src/runtimes/web/dom/jsonp_request.d.ts +10 -0
  397. package/types/src/runtimes/web/dom/script_receiver.d.ts +7 -0
  398. package/types/src/runtimes/web/dom/script_receiver_factory.d.ts +10 -0
  399. package/types/src/runtimes/web/dom/script_request.d.ts +9 -0
  400. package/types/src/runtimes/web/http/http.d.ts +2 -0
  401. package/types/src/runtimes/web/http/http_xdomain_request.d.ts +3 -0
  402. package/types/src/runtimes/web/net_info.d.ts +7 -0
  403. package/types/src/runtimes/web/runtime.d.ts +3 -0
  404. package/types/src/runtimes/web/timeline/jsonp_timeline.d.ts +6 -0
  405. package/types/src/runtimes/web/transports/transport_connection_initializer.d.ts +1 -0
  406. package/types/src/runtimes/web/transports/transports.d.ts +2 -0
  407. package/types/src/runtimes/worker/auth/fetch_auth.d.ts +3 -0
  408. package/types/src/runtimes/worker/net_info.d.ts +6 -0
  409. package/types/src/runtimes/worker/runtime.d.ts +3 -0
  410. package/types/src/runtimes/worker/timeline/fetch_timeline.d.ts +6 -0
  411. package/vite.config.js +52 -0
  412. package/vite.config.node.js +72 -0
  413. package/webpack/config.node.js +26 -0
  414. package/webpack/config.react-native.js +35 -0
  415. package/webpack/config.shared.js +50 -0
  416. package/webpack/config.web.js +36 -0
  417. package/webpack/config.worker.js +42 -0
  418. package/webpack/dev.server.js +17 -0
  419. package/webpack/hosting_config.js +6 -0
  420. package/with-encryption/index.d.ts +29 -0
  421. package/with-encryption/index.js +4 -0
  422. package/worker/index.d.ts +29 -0
  423. package/worker/index.js +1 -0
  424. package/worker/with-encryption/index.d.ts +29 -0
  425. package/worker/with-encryption/index.js +1 -0
@@ -0,0 +1,940 @@
1
+ # Pusher-JS Library Structure Analysis
2
+
3
+ ## Overview
4
+ This document provides a comprehensive analysis of the pusher-js library architecture, focusing on areas relevant for implementing delta compression and rate cache sync features.
5
+
6
+ **Library**: pusher-js v8.4.0
7
+ **Type**: Real-time messaging client for browsers, React Native, Node.js
8
+ **Architecture**: Event-driven, multi-transport with WebSocket and HTTP fallback
9
+
10
+ ---
11
+
12
+ ## 1. Main Library Structure and Entry Points
13
+
14
+ ### Root Entry Point: `/src/core/pusher.ts`
15
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\pusher.ts`
16
+
17
+ **Key Responsibilities**:
18
+ - Main Pusher class that serves as the public API entry point
19
+ - Creates and manages connection, channels, and events dispatcher
20
+ - Manages channel subscriptions and event forwarding
21
+ - Handles session ID generation and timeline tracking
22
+
23
+ **Key Properties**:
24
+ ```typescript
25
+ export default class Pusher {
26
+ key: string; // Application key
27
+ config: Config; // Connection configuration
28
+ channels: Channels; // Channel management
29
+ global_emitter: EventsDispatcher; // Global event dispatcher
30
+ sessionID: number; // Unique session identifier
31
+ timeline: Timeline; // Event timeline for debugging
32
+ timelineSender: TimelineSender; // Stats transmission
33
+ connection: ConnectionManager; // Connection lifecycle manager
34
+ user: UserFacade; // User authentication
35
+ }
36
+ ```
37
+
38
+ **Key Methods**:
39
+ - `subscribe(channel_name)` - Subscribe to a channel
40
+ - `unsubscribe(channel_name)` - Unsubscribe from a channel
41
+ - `send_event(event_name, data, channel)` - Send client event
42
+ - `bind(event_name, callback)` - Bind to global events
43
+ - `channel(name)` - Get channel instance
44
+
45
+ **Message Flow in Constructor**:
46
+ ```typescript
47
+ this.connection.bind('message', (event) => {
48
+ var eventName = event.event;
49
+ var internal = eventName.indexOf('pusher_internal:') === 0;
50
+ if (event.channel) {
51
+ var channel = this.channel(event.channel);
52
+ if (channel) {
53
+ channel.handleEvent(event); // Delegate to channel
54
+ }
55
+ }
56
+ // Emit globally [deprecated]
57
+ if (!internal) {
58
+ this.global_emitter.emit(event.event, event.data);
59
+ }
60
+ });
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 2. Protocol Messages Handling
66
+
67
+ ### Message Type Definitions: `/src/core/connection/protocol/message-types.ts`
68
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\connection\protocol\message-types.ts`
69
+
70
+ **Core Message Structure**:
71
+ ```typescript
72
+ interface PusherEvent {
73
+ event: string; // Event name
74
+ channel?: string; // Channel name (optional)
75
+ data?: any; // Event payload
76
+ user_id?: string; // User ID for presence channels (optional)
77
+ }
78
+ ```
79
+
80
+ ### Protocol Handler: `/src/core/connection/protocol/protocol.ts`
81
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\connection\protocol\protocol.ts`
82
+
83
+ **Responsibilities**:
84
+ - Encode/decode messages in Pusher format
85
+ - Process handshake messages
86
+ - Handle close event actions and error classification
87
+
88
+ **Key Functions**:
89
+
90
+ 1. **decodeMessage(messageEvent: MessageEvent): PusherEvent**
91
+ - Parses incoming WebSocket message
92
+ - Handles nested JSON data in pusher event data field
93
+ - Throws `MessageParseError` on invalid JSON
94
+ - **Integration Point**: Messages arrive as JSON strings, need decompression BEFORE this step
95
+
96
+ 2. **encodeMessage(event: PusherEvent): string**
97
+ - Serializes Pusher events to JSON
98
+ - **Integration Point**: Delta compression could be applied AFTER this step
99
+
100
+ 3. **processHandshake(messageEvent): Action**
101
+ - Processes connection_established or error messages
102
+ - Returns action with socket_id and activityTimeout
103
+ - **Relevant for**: Cache sync initialization
104
+
105
+ 4. **getCloseAction(closeEvent): string**
106
+ - Maps close codes to actions: 'connected', 'refused', 'backoff', 'retry', 'tls_only'
107
+
108
+ **Example Message Flow**:
109
+ ```
110
+ Raw WebSocket data: '{"event":"pusher:subscribe","data":{"auth":"xyz"}}'
111
+
112
+ Protocol.decodeMessage()
113
+
114
+ Decoded PusherEvent: {event: "pusher:subscribe", data: {auth: "xyz"}}
115
+
116
+ Channel.handleEvent()
117
+ ```
118
+
119
+ ---
120
+
121
+ ## 3. Channel Subscriptions and Event Processing
122
+
123
+ ### Channel Management: `/src/core/channels/channels.ts`
124
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\channels\channels.ts`
125
+
126
+ **Responsibilities**:
127
+ - Maintains channel registry/map
128
+ - Creates appropriate channel type (public/private/presence/encrypted)
129
+ - Proxies disconnect signals to all channels
130
+
131
+ **Key Methods**:
132
+ ```typescript
133
+ class Channels {
134
+ channels: ChannelTable; // Dictionary of channels
135
+
136
+ add(name: string, pusher: Pusher): Channel // Create/retrieve
137
+ find(name: string): Channel // Lookup
138
+ remove(name: string): Channel // Delete
139
+ all(): Channel[] // Get all
140
+ disconnect(): void // Disconnect all
141
+ }
142
+ ```
143
+
144
+ **Channel Type Factory** (in `createChannel()`):
145
+ - `private-encrypted-*` → EncryptedChannel (with nacl)
146
+ - `private-*` → PrivateChannel
147
+ - `presence-*` → PresenceChannel
148
+ - others → Channel (public)
149
+
150
+ ### Base Channel Class: `/src/core/channels/channel.ts`
151
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\channels\channel.ts`
152
+
153
+ **Extends**: EventsDispatcher (inherits emit/bind/unbind)
154
+
155
+ **State Management**:
156
+ ```typescript
157
+ class Channel extends EventsDispatcher {
158
+ name: string;
159
+ pusher: Pusher;
160
+ subscribed: boolean; // Currently subscribed
161
+ subscriptionPending: boolean; // Subscription in progress
162
+ subscriptionCancelled: boolean; // Pending cancellation
163
+ subscriptionCount: null; // For subscription_count events
164
+ }
165
+ ```
166
+
167
+ **Key Methods - Event Handling**:
168
+
169
+ 1. **handleEvent(event: PusherEvent)**
170
+ - Routes internal vs. user events
171
+ - Handles special internal events: subscription_succeeded, subscription_count
172
+ - Emits user events with metadata
173
+ - **Integration Point**: Delta decompression should happen BEFORE this
174
+
175
+ 2. **handleSubscriptionSucceededEvent(event)**
176
+ - Updates subscribed state
177
+ - Emits 'pusher:subscription_succeeded'
178
+ - Handles subscription cancellation race condition
179
+
180
+ 3. **subscribe()**
181
+ - Authorizes via channel.authorize() callback
182
+ - Sends 'pusher:subscribe' message with auth data
183
+ - Handles authorization errors
184
+
185
+ 4. **trigger(event, data)**
186
+ - Client-side event publishing
187
+ - Validates event name starts with 'client-'
188
+ - Calls pusher.send_event()
189
+
190
+ **Event Emission Flow**:
191
+ ```
192
+ Connection → Pusher.message → Channel.handleEvent()
193
+
194
+ Is internal event?
195
+ ↙ ↘
196
+ NO YES
197
+ ↓ ↓
198
+ Emit user event Handle internal
199
+ with metadata (subscription_succeeded,
200
+ subscription_count)
201
+ ```
202
+
203
+ ### Presence Channels: `/src/core/channels/presence_channel.ts`
204
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\channels\presence_channel.ts`
205
+
206
+ **Extends**: PrivateChannel
207
+
208
+ **Additional Responsibilities**:
209
+ - Members state management
210
+ - Presence event handling: member_added, member_removed
211
+ - User ID association with presence data
212
+
213
+ **Key Difference**:
214
+ ```typescript
215
+ handleEvent(event: PusherEvent) {
216
+ // Includes metadata.user_id for presence events
217
+ var metadata: Metadata = {};
218
+ if (event.user_id) {
219
+ metadata.user_id = event.user_id;
220
+ }
221
+ this.emit(eventName, data, metadata);
222
+ }
223
+ ```
224
+
225
+ ---
226
+
227
+ ## 4. Event Handling and Dispatch System
228
+
229
+ ### Event Dispatcher: `/src/core/events/dispatcher.ts`
230
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\events\dispatcher.ts`
231
+
232
+ **Core Responsibility**: Manage callback bindings and event emission
233
+
234
+ **Architecture**:
235
+ ```typescript
236
+ class Dispatcher {
237
+ callbacks: CallbackRegistry; // Event → [callbacks]
238
+ global_callbacks: Function[]; // Callbacks for all events
239
+ failThrough?: Function; // Called if no callbacks bound
240
+ }
241
+ ```
242
+
243
+ **Key Methods**:
244
+
245
+ 1. **bind(eventName, callback, context?)**
246
+ - Register callback for specific event
247
+ - Maintains context binding
248
+ - Returns this (chainable)
249
+
250
+ 2. **bind_global(callback)**
251
+ - Register callback for ALL events
252
+ - Callback receives (eventName, data) arguments
253
+
254
+ 3. **emit(eventName, data?, metadata?)**
255
+ - Call all global callbacks: `global_callback(eventName, data)`
256
+ - Call event-specific callbacks: `callback(data, metadata?)`
257
+ - Falls back to failThrough if no callbacks
258
+ - **Integration Point**: Event data passes through here; compression/decompression happens before
259
+
260
+ 4. **unbind/unbind_global/unbind_all**
261
+ - Deregister callbacks
262
+
263
+ **Emission Flow**:
264
+ ```typescript
265
+ emit(eventName: string, data?: any, metadata?: Metadata): Dispatcher {
266
+ // 1. Call global callbacks
267
+ for (var i = 0; i < this.global_callbacks.length; i++) {
268
+ this.global_callbacks[i](eventName, data);
269
+ }
270
+
271
+ // 2. Get event-specific callbacks
272
+ var callbacks = this.callbacks.get(eventName);
273
+
274
+ // 3. Build arguments (data + metadata)
275
+ var args = [];
276
+ if (metadata) {
277
+ args.push(data, metadata);
278
+ } else if (data) {
279
+ args.push(data);
280
+ }
281
+
282
+ // 4. Call all callbacks
283
+ if (callbacks && callbacks.length > 0) {
284
+ for (var i = 0; i < callbacks.length; i++) {
285
+ callbacks[i].fn.apply(callbacks[i].context || global, args);
286
+ }
287
+ } else if (this.failThrough) {
288
+ this.failThrough(eventName, data);
289
+ }
290
+
291
+ return this;
292
+ }
293
+ ```
294
+
295
+ ### Callback Registry: `/src/core/events/callback_registry.ts`
296
+ **Manages**: Event name → [Callback objects]
297
+
298
+ ```typescript
299
+ interface Callback {
300
+ fn: Function;
301
+ context?: any;
302
+ }
303
+ ```
304
+
305
+ ---
306
+
307
+ ## 5. Connection Management and Message Flow
308
+
309
+ ### Connection Manager: `/src/core/connection/connection_manager.ts`
310
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\connection\connection_manager.ts`
311
+
312
+ **Responsibilities**:
313
+ - Lifecycle management (connecting, connected, disconnected, failed, unavailable)
314
+ - Activity checks (ping/pong)
315
+ - Strategy selection and execution
316
+ - Network reachability monitoring
317
+ - Error handling and retry logic
318
+
319
+ **State Machine**:
320
+ ```
321
+ initialized → connecting → connected → disconnected
322
+ ↓ (error)
323
+ unavailable → connecting (retry)
324
+ ↓ (strategy not supported)
325
+ failed
326
+ ```
327
+
328
+ **Key Properties**:
329
+ ```typescript
330
+ class ConnectionManager extends EventsDispatcher {
331
+ key: string;
332
+ state: string; // Current connection state
333
+ connection: Connection; // Active connection
334
+ socket_id: string; // Socket ID from server
335
+ strategy: Strategy; // Transport selection strategy
336
+ runner: StrategyRunner; // Active strategy runner
337
+ activityTimeout: number; // Activity check interval
338
+ usingTLS: boolean;
339
+ }
340
+ ```
341
+
342
+ **Key Methods**:
343
+
344
+ 1. **connect()**
345
+ - Initiates connection attempt
346
+ - Updates state to 'connecting'
347
+ - Sets unavailableTimer
348
+
349
+ 2. **send(data)**
350
+ - Raw data transmission via active connection
351
+ - Returns false if no connection
352
+
353
+ 3. **send_event(name, data, channel?)**
354
+ - Event-level transmission
355
+ - Delegates to connection.send_event()
356
+
357
+ 4. **disconnect()**
358
+ - Graceful disconnection
359
+ - Updates state to 'disconnected'
360
+
361
+ **Connection Callback Handlers**:
362
+ ```typescript
363
+ private buildConnectionCallbacks(errorCallbacks): ConnectionCallbacks {
364
+ return {
365
+ message: (message) => {
366
+ // MAIN MESSAGE HANDLER
367
+ this.resetActivityCheck();
368
+ this.emit('message', message); // Emitted to Pusher instance
369
+ },
370
+ ping: () => {
371
+ this.send_event('pusher:pong', {}); // Reply to server ping
372
+ },
373
+ activity: () => {
374
+ this.resetActivityCheck(); // Reset activity timer
375
+ },
376
+ error: (error) => {
377
+ this.emit('error', error);
378
+ },
379
+ closed: () => {
380
+ this.abandonConnection();
381
+ if (this.shouldRetry()) {
382
+ this.retryIn(1000);
383
+ }
384
+ },
385
+ };
386
+ }
387
+ ```
388
+
389
+ **Message Reception Flow**:
390
+ ```
391
+ Transport receives data
392
+
393
+ Connection.bindListeners (message handler)
394
+
395
+ Protocol.decodeMessage(messageEvent)
396
+
397
+ Connection emits 'message' with decoded PusherEvent
398
+
399
+ ConnectionManager message callback
400
+
401
+ ConnectionManager.emit('message', message)
402
+
403
+ Pusher instance listens to connection 'message'
404
+
405
+ Pusher delegates to Channel.handleEvent()
406
+ ```
407
+
408
+ ### Connection: `/src/core/connection/connection.ts`
409
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\connection\connection.ts`
410
+
411
+ **Responsibilities**:
412
+ - Protocol-level message handling
413
+ - Transport abstraction
414
+ - Ping/pong management
415
+ - Error routing
416
+
417
+ **Key Methods**:
418
+
419
+ 1. **send(data: any): boolean**
420
+ - Raw string/data transmission
421
+
422
+ 2. **send_event(name, data, channel?): boolean**
423
+ - Creates PusherEvent, encodes via Protocol.encodeMessage()
424
+ - Sends via transport
425
+
426
+ 3. **ping()**
427
+ - If transport supports native ping: use it
428
+ - Otherwise: send 'pusher:ping' event
429
+
430
+ **Transport Listener Binding**:
431
+ ```typescript
432
+ private bindListeners() {
433
+ var listeners = {
434
+ message: (messageEvent: MessageEvent) => {
435
+ var pusherEvent;
436
+ try {
437
+ pusherEvent = Protocol.decodeMessage(messageEvent); // JSON parsing
438
+ } catch (e) {
439
+ this.emit('error', {
440
+ type: 'MessageParseError',
441
+ error: e,
442
+ data: messageEvent.data,
443
+ });
444
+ }
445
+
446
+ if (pusherEvent !== undefined) {
447
+ Logger.debug('Event recd', pusherEvent);
448
+
449
+ switch (pusherEvent.event) {
450
+ case 'pusher:error':
451
+ this.emit('error', {
452
+ type: 'PusherError',
453
+ data: pusherEvent.data,
454
+ });
455
+ break;
456
+ case 'pusher:ping':
457
+ this.emit('ping');
458
+ break;
459
+ case 'pusher:pong':
460
+ this.emit('pong');
461
+ break;
462
+ }
463
+ this.emit('message', pusherEvent); // Main emission
464
+ }
465
+ },
466
+ // ... other listeners
467
+ };
468
+ }
469
+ ```
470
+
471
+ **Integration Point for Delta Compression**:
472
+ After `Protocol.decodeMessage()` successfully parses JSON, the data needs decompression if it was compressed.
473
+
474
+ ---
475
+
476
+ ## 6. Existing Compression/Optimization Features
477
+
478
+ ### Transport Caching Strategy: `/src/core/strategies/websocket_prioritized_cached_strategy.ts`
479
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\strategies\websocket_prioritized_cached_strategy.ts`
480
+
481
+ **Current Optimization**: Transport selection caching (not message compression)
482
+
483
+ **What it Does**:
484
+ - Caches the last successful transport (WebSocket vs HTTP fallback)
485
+ - Stores in localStorage with TTL (default 30 minutes)
486
+ - Skips cache after 3 failures to force re-evaluation
487
+ - Measures latency for quick retry on subsequent connections
488
+
489
+ **Cached Data Structure**:
490
+ ```typescript
491
+ {
492
+ timestamp: number, // When cached
493
+ transport: string, // 'ws', 'wss', 'xhr_streaming', etc.
494
+ latency: number, // Round-trip time in ms
495
+ cacheSkipCount: number, // Failures before re-trying cache
496
+ }
497
+ ```
498
+
499
+ **Storage Key**: `'pusherTransport' + (usingTLS ? 'TLS' : 'NonTLS')`
500
+
501
+ **Relevant Code**:
502
+ ```typescript
503
+ function fetchTransportCache(usingTLS: boolean): any {
504
+ var storage = Runtime.getLocalStorage();
505
+ if (storage) {
506
+ try {
507
+ var serializedCache = storage[getTransportCacheKey(usingTLS)];
508
+ if (serializedCache) {
509
+ return JSON.parse(serializedCache);
510
+ }
511
+ } catch (e) {
512
+ flushTransportCache(usingTLS);
513
+ }
514
+ }
515
+ return null;
516
+ }
517
+
518
+ function storeTransportCache(
519
+ usingTLS: boolean,
520
+ transport: TransportStrategy,
521
+ latency: number,
522
+ cacheSkipCount: number,
523
+ ) {
524
+ var storage = Runtime.getLocalStorage();
525
+ if (storage) {
526
+ try {
527
+ storage[getTransportCacheKey(usingTLS)] = Collections.safeJSONStringify({
528
+ timestamp: Util.now(),
529
+ transport: transport,
530
+ latency: latency,
531
+ cacheSkipCount: cacheSkipCount,
532
+ });
533
+ } catch (e) {
534
+ // catch over quota exceptions
535
+ }
536
+ }
537
+ }
538
+ ```
539
+
540
+ ### JSON Encoding/Decoding
541
+ All messages use standard JSON serialization:
542
+
543
+ **Protocol.encodeMessage()**:
544
+ ```typescript
545
+ encodeMessage: function (event: PusherEvent): string {
546
+ return JSON.stringify(event);
547
+ },
548
+ ```
549
+
550
+ **Protocol.decodeMessage()**:
551
+ ```typescript
552
+ decodeMessage: function (messageEvent: MessageEvent): PusherEvent {
553
+ try {
554
+ var messageData = JSON.parse(messageEvent.data);
555
+ var pusherEventData = messageData.data;
556
+ if (typeof pusherEventData === 'string') {
557
+ try {
558
+ pusherEventData = JSON.parse(messageData.data); // Nested JSON
559
+ } catch (e) {}
560
+ }
561
+ // ... return PusherEvent
562
+ } catch (e) {
563
+ throw { type: 'MessageParseError', error: e, data: messageEvent.data };
564
+ }
565
+ },
566
+ ```
567
+
568
+ ### Safe JSON Serialization: `/src/core/utils/collections.ts`
569
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\utils\collections.ts`
570
+
571
+ **Function**: `safeJSONStringify(source: any): string`
572
+
573
+ **Purpose**: Handle circular references (important for React Native)
574
+
575
+ **Implementation**:
576
+ ```typescript
577
+ export function safeJSONStringify(source: any): string {
578
+ try {
579
+ return JSON.stringify(source);
580
+ } catch (e) {
581
+ return JSON.stringify(decycleObject(source));
582
+ }
583
+ }
584
+ ```
585
+
586
+ Uses Douglas Crockford's cycle.js technique to break circular references before stringification.
587
+
588
+ **Relevant for**: Compression should use safeJSONStringify to avoid issues with circular structures.
589
+
590
+ ---
591
+
592
+ ## 7. Data Structure and Message Metadata
593
+
594
+ ### Event Metadata: `/src/core/channels/metadata.ts`
595
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\channels/metadata.ts`
596
+
597
+ ```typescript
598
+ interface Metadata {
599
+ user_id?: string; // Present in presence channel events
600
+ }
601
+ ```
602
+
603
+ Used to pass additional context to event callbacks (especially for presence events).
604
+
605
+ ### Action Response: `/src/core/connection/protocol/action.ts`
606
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core\connection/protocol/action.ts`
607
+
608
+ ```typescript
609
+ interface Action {
610
+ action: string; // 'connected', 'refused', 'backoff', etc.
611
+ id?: string; // socket_id
612
+ activityTimeout?: number; // Server-specified activity timeout
613
+ error?: any; // Error details
614
+ }
615
+ ```
616
+
617
+ ---
618
+
619
+ ## 8. Timeline/Diagnostics System
620
+
621
+ ### Timeline: `/src/core/timeline/timeline.ts`
622
+
623
+ The library includes a diagnostics timeline system that tracks:
624
+ - Connection events
625
+ - Transport selection
626
+ - Errors
627
+ - Performance metrics
628
+ - State transitions
629
+
630
+ **Initialized in Pusher constructor**:
631
+ ```typescript
632
+ this.timeline = new Timeline(this.key, this.sessionID, {
633
+ cluster: this.config.cluster,
634
+ features: Pusher.getClientFeatures(),
635
+ params: this.config.timelineParams || {},
636
+ limit: 50,
637
+ level: TimelineLevel.INFO,
638
+ version: Defaults.VERSION,
639
+ });
640
+ ```
641
+
642
+ Sent periodically (every 60 seconds) if `enableStats: true`.
643
+
644
+ **Integration Point**: Could be used to track compression statistics and cache sync metrics.
645
+
646
+ ---
647
+
648
+ ## 9. Configuration and Defaults
649
+
650
+ ### Default Configuration: `/src/core/defaults.ts`
651
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core/defaults.ts`
652
+
653
+ ```typescript
654
+ {
655
+ VERSION: string,
656
+ PROTOCOL: 7,
657
+
658
+ // Timeouts
659
+ activityTimeout: 120000, // 2 minutes
660
+ pongTimeout: 30000, // 30 seconds
661
+ unavailableTimeout: 10000, // 10 seconds
662
+
663
+ // Transport ports
664
+ wsPort: 80,
665
+ wssPort: 443,
666
+
667
+ // Endpoints
668
+ authEndpoint: '/pusher/auth',
669
+ stats_host: 'stats.pusher.com',
670
+ }
671
+ ```
672
+
673
+ ### Config Builder: `/src/core/config.ts`
674
+ **Path**: `C:\Users\radu0\Desktop\Code\Javascript\sockudo-js\src\core/config.ts`
675
+
676
+ - Merges user options with defaults
677
+ - Validates configuration
678
+ - Builds authentication handlers
679
+
680
+ ---
681
+
682
+ ## 10. Integration Points for New Features
683
+
684
+ ### Delta Compression Integration Points
685
+
686
+ **1. Outgoing Message Compression** (Client → Server):
687
+ ```
688
+ Pusher.send_event()
689
+ → Connection.send_event()
690
+ → Protocol.encodeMessage() [returns JSON string]
691
+ → [COMPRESSION POINT] Apply delta compression
692
+ → Connection.send() [transmit compressed data]
693
+ ```
694
+
695
+ **2. Incoming Message Decompression** (Server → Client):
696
+ ```
697
+ Transport receives raw data
698
+ → Connection.bindListeners.message()
699
+ → [DECOMPRESSION POINT] Detect and decompress if needed
700
+ → Protocol.decodeMessage() [parse JSON]
701
+ → Connection.emit('message', pusherEvent)
702
+ → ConnectionManager.message callback
703
+ → Pusher instance receives
704
+ → Channel.handleEvent()
705
+ → Dispatcher.emit() [call user callbacks]
706
+ ```
707
+
708
+ **Implementation Locations**:
709
+ 1. **Compression/Decompression Module**: New utility in `/src/core/compression/` or `/src/core/utils/compression.ts`
710
+ 2. **Connection.send_event()**: Add compression before `this.send()`
711
+ 3. **Connection.bindListeners()**: Add decompression in message handler before `Protocol.decodeMessage()`
712
+ 4. **Protocol**: Optional - add compression support flags to protocol
713
+
714
+ ### Rate Cache Sync Integration Points
715
+
716
+ **1. Cache Storage**:
717
+ - Use existing localStorage pattern from `WebSocketPrioritizedCachedStrategy`
718
+ - Store channel state snapshots with version/timestamp
719
+ - Location: `/src/core/cache/` or `/src/core/strategies/cache_sync_strategy.ts`
720
+
721
+ **2. Subscription Sync**:
722
+ ```
723
+ Channel.subscribe()
724
+ → Authorize()
725
+ → Check cache for existing state
726
+ → If valid: restore from cache
727
+ → Send 'pusher:subscribe'
728
+ ```
729
+
730
+ **3. Event Rate Limiting**:
731
+ - Add to `Dispatcher.emit()` or `Channel.handleEvent()`
732
+ - Implement token bucket or sliding window
733
+ - Track per-event or per-channel
734
+
735
+ **4. Cache Update Hooks**:
736
+ - On `pusher:subscription_succeeded` - capture state
737
+ - On new events - update cache incrementally
738
+ - On connection loss - persist for recovery
739
+
740
+ **Suggested Locations**:
741
+ 1. **Cache Manager**: `/src/core/cache/cache_manager.ts`
742
+ 2. **Rate Limiter**: `/src/core/utils/rate_limiter.ts`
743
+ 3. **Extensions**: Modify `Channel.handleEvent()` and `Channel.subscribe()`
744
+
745
+ ---
746
+
747
+ ## 11. File Structure Reference
748
+
749
+ ```
750
+ src/core/
751
+ ├── pusher.ts [Main entry point]
752
+ ├── connection/
753
+ │ ├── connection_manager.ts [Connection lifecycle]
754
+ │ ├── connection.ts [Protocol adapter]
755
+ │ ├── callbacks.ts [Type definitions]
756
+ │ └── protocol/
757
+ │ ├── protocol.ts [Message encode/decode]
758
+ │ ├── message-types.ts [PusherEvent interface]
759
+ │ └── action.ts [Server response types]
760
+ ├── channels/
761
+ │ ├── channels.ts [Channel registry]
762
+ │ ├── channel.ts [Base channel]
763
+ │ ├── presence_channel.ts [Presence-aware channel]
764
+ │ ├── private_channel.ts [Auth channel]
765
+ │ ├── encrypted_channel.ts [End-to-end encrypted]
766
+ │ ├── members.ts [Presence members]
767
+ │ └── metadata.ts [Event metadata]
768
+ ├── events/
769
+ │ ├── dispatcher.ts [Event emitter]
770
+ │ ├── callback.ts [Callback wrapper]
771
+ │ ├── callback_registry.ts [Callback storage]
772
+ │ └── callback_table.ts [Type definitions]
773
+ ├── transports/
774
+ │ ├── transport.ts [Transport interface]
775
+ │ ├── transport_connection.ts [Transport adapter]
776
+ │ ├── transport_manager.ts [Multi-transport handler]
777
+ │ └── transports_table.ts [Available transports]
778
+ ├── strategies/
779
+ │ ├── strategy.ts [Strategy interface]
780
+ │ ├── websocket_prioritized_cached_strategy.ts [Caching]
781
+ │ └── transport_strategy.ts [Transport selection]
782
+ ├── timeline/
783
+ │ ├── timeline.ts [Diagnostics]
784
+ │ ├── timeline_sender.ts [Send metrics]
785
+ │ └── level.ts [Log levels]
786
+ ├── utils/
787
+ │ ├── collections.ts [Utility functions]
788
+ │ ├── factory.ts [Object creation]
789
+ │ ├── flat_promise.ts [Promise wrapper]
790
+ │ ├── url_store.ts [URL utilities]
791
+ │ └── timers/
792
+ │ ├── abstract_timer.ts
793
+ │ ├── timed_callback.ts
794
+ │ └── scheduling.ts
795
+ ├── http/ [HTTP fallback transport]
796
+ ├── auth/ [Authentication]
797
+ ├── config.ts [Configuration]
798
+ ├── defaults.ts [Default values]
799
+ ├── options.ts [Options validation]
800
+ ├── util.ts [Utility helpers]
801
+ └── socket.ts [Socket interface]
802
+ ```
803
+
804
+ ---
805
+
806
+ ## 12. Key Message Flows
807
+
808
+ ### Subscription Flow
809
+ ```
810
+ 1. Pusher.subscribe("channel-name")
811
+
812
+ 2. Channels.add() creates Channel instance
813
+
814
+ 3. If not subscribed and connected:
815
+ Channel.subscribe()
816
+
817
+ 4. Channel.authorize() [callback for auth]
818
+
819
+ 5. Connection.send_event('pusher:subscribe', {auth, channel_data})
820
+
821
+ 6. Server receives and broadcasts subscription_succeeded
822
+
823
+ 7. Connection receives 'pusher_internal:subscription_succeeded'
824
+
825
+ 8. Channel.handleSubscriptionSucceededEvent()
826
+
827
+ 9. Channel emits 'pusher:subscription_succeeded'
828
+ ```
829
+
830
+ ### Event Publication Flow
831
+ ```
832
+ 1. User calls channel.bind('my-event', callback)
833
+
834
+ 2. Dispatcher.bind(eventName, callback) stores callback
835
+
836
+ 3. Server publishes event to channel
837
+
838
+ 4. Transport receives JSON: {"event":"my-event","channel":"...", "data":{...}}
839
+
840
+ 5. Connection.message handler:
841
+ - Protocol.decodeMessage() parses JSON
842
+ - Emits 'message' event
843
+
844
+ 6. ConnectionManager.message callback:
845
+ - Resets activity timer
846
+ - Emits 'message' to Pusher
847
+
848
+ 7. Pusher.connection binds to 'message':
849
+ - Finds channel
850
+ - Calls channel.handleEvent()
851
+
852
+ 8. Channel.handleEvent():
853
+ - If user event: Dispatcher.emit(eventName, data, metadata)
854
+
855
+ 9. Dispatcher.emit():
856
+ - Calls all callbacks with (data, metadata)
857
+ ```
858
+
859
+ ### Connection Establishment Flow
860
+ ```
861
+ 1. Pusher.connect()
862
+ → ConnectionManager.connect()
863
+
864
+ 2. Strategy selects transport (ws, wss, xhr_streaming, etc.)
865
+
866
+ 3. Transport connects and sends initial handshake
867
+
868
+ 4. Protocol.processHandshake():
869
+ - Expects 'pusher:connection_established'
870
+ - Returns Action with socket_id and activityTimeout
871
+
872
+ 5. HandshakeCallback.connected():
873
+ - Set socket_id
874
+ - Update state to 'connected'
875
+ - Emit 'connected' event
876
+
877
+ 6. Pusher.connection binds to 'connected':
878
+ - Calls subscribeAll()
879
+
880
+ 7. For each channel:
881
+ - If subscriptionPending: Channel.reinstateSubscription()
882
+ - Else if connected: Channel.subscribe()
883
+
884
+ 8. Channel authorization and subscription occurs
885
+ ```
886
+
887
+ ---
888
+
889
+ ## 13. Recommendations for Feature Implementation
890
+
891
+ ### Delta Compression
892
+ **Considerations**:
893
+ 1. Bidirectional: Need compression for both incoming and outgoing
894
+ 2. Optional: Must not break compatibility; use protocol version or feature flags
895
+ 3. Performance: Only compress messages above a minimum size threshold
896
+ 4. Caching: Maintain compression context/dictionary per connection
897
+ 5. Error handling: Graceful fallback to uncompressed if decompression fails
898
+
899
+ **Integration Points** (Priority Order):
900
+ 1. Create `/src/core/compression/delta_compressor.ts`
901
+ 2. Modify `Connection.bindListeners()` - decompress incoming
902
+ 3. Modify `Connection.send_event()` - compress outgoing
903
+ 4. Add compression flag to handshake `ConnectionCallbacks`
904
+ 5. Update `Protocol` to support compression metadata
905
+
906
+ ### Rate Cache Sync
907
+ **Considerations**:
908
+ 1. State Recovery: Cache channel subscriptions across page reloads
909
+ 2. Incremental Sync: Only sync changed state, not full state
910
+ 3. TTL: Implement cache expiration with per-channel versioning
911
+ 4. Rate Limiting: Separate from caching; implement token bucket
912
+ 5. Storage: Use localStorage for browser, memory for Node.js
913
+
914
+ **Integration Points** (Priority Order):
915
+ 1. Create `/src/core/cache/cache_manager.ts` for storage abstraction
916
+ 2. Create `/src/core/utils/rate_limiter.ts` for rate control
917
+ 3. Modify `Channel.subscribe()` - check cache before subscribe
918
+ 4. Modify `Channel.handleSubscriptionSucceededEvent()` - update cache
919
+ 5. Modify `Dispatcher.emit()` - apply rate limiting
920
+ 6. Add lifecycle methods to `ConnectionManager` for cache sync on reconnect
921
+
922
+ ---
923
+
924
+ ## Summary
925
+
926
+ The pusher-js library is well-structured with clear separation of concerns:
927
+
928
+ - **Connection Layer**: Manages transport and protocol
929
+ - **Channel Layer**: Manages subscriptions and event routing
930
+ - **Event Layer**: Dispatcher system for callback management
931
+ - **Message Flow**: Unidirectional from transport → connection → channels → user callbacks
932
+
933
+ For **delta compression**: Insert at Connection message handler (decompress) and send_event (compress)
934
+ For **rate cache sync**: Implement cache layer and integrate with Channel subscribe/handle methods
935
+
936
+ Both features require careful consideration of:
937
+ - Backward compatibility (feature negotiation)
938
+ - Error handling and fallback
939
+ - Cross-platform support (browser, React Native, Node.js)
940
+ - Existing caching patterns (see WebSocketPrioritizedCachedStrategy)