@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.
- package/.editorconfig +14 -0
- package/.github/ISSUE_TEMPLATE.md +11 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- package/.github/dependabot.yml +14 -0
- package/.github/stale.yml +26 -0
- package/.github/workflows/release.yml +112 -0
- package/.github/workflows/release_pr.yml +43 -0
- package/.github/workflows/run-tests.yml +62 -0
- package/.gitmodules +3 -0
- package/.prettierrc +2 -0
- package/CHANGELOG.md +928 -0
- package/DELTA_COMPRESSION.md +365 -0
- package/DELTA_USAGE.md +179 -0
- package/IMPLEMENTATION_SUMMARY.md +261 -0
- package/IMPORT_GUIDE.md +638 -0
- package/LIBRARY_STRUCTURE_ANALYSIS.md +940 -0
- package/LICENCE +19 -0
- package/Makefile +14 -0
- package/README.md +709 -0
- package/TAG_FILTERING_CLIENT.md +471 -0
- package/bower.json +19 -0
- package/bun.lock +2695 -0
- package/dist/node/filter.js +252 -0
- package/dist/node/filter.js.map +1 -0
- package/dist/node/pusher.js +4434 -0
- package/dist/node/pusher.js.map +1 -0
- package/dist/web/filter.mjs +252 -0
- package/dist/web/filter.mjs.map +1 -0
- package/dist/web/pusher.mjs +5889 -0
- package/dist/web/pusher.mjs.map +1 -0
- package/examples/delta-compression-example.html +372 -0
- package/examples/delta-seamless-example.html +185 -0
- package/index.d.ts +36 -0
- package/integration_tests_server/index.js +176 -0
- package/integration_tests_server/package-lock.json +1177 -0
- package/integration_tests_server/package.json +15 -0
- package/interactive/.env +16 -0
- package/interactive/CONFLATION_TEST.md +73 -0
- package/interactive/DELTA_COMPRESSION_TESTING.md +262 -0
- package/interactive/bun.lock +208 -0
- package/interactive/package-lock.json +1075 -0
- package/interactive/package.json +32 -0
- package/interactive/public/app.js +1363 -0
- package/interactive/public/bundle-entry.js +14 -0
- package/interactive/public/conflation-test.html +508 -0
- package/interactive/public/conflation-test.js +785 -0
- package/interactive/public/delta-compression.js +1090 -0
- package/interactive/public/dist/bundle.js +5857 -0
- package/interactive/public/index.html +392 -0
- package/interactive/public/main.js +20 -0
- package/interactive/public/style.css +823 -0
- package/interactive/server.js +246 -0
- package/interactive/test-bundle.html +89 -0
- package/interactive/test-delta.js +146 -0
- package/node.js +1 -0
- package/package.json +94 -0
- package/pusher-with-encryption/index.js +1 -0
- package/react-native/index.d.ts +29 -0
- package/react-native/index.js +1 -0
- package/spec/config/jasmine/helpers/reporter.js +14 -0
- package/spec/config/jasmine/integration.json +13 -0
- package/spec/config/jasmine/unit.json +13 -0
- package/spec/config/jasmine/webpack.integration.js +33 -0
- package/spec/config/jasmine/webpack.unit.js +30 -0
- package/spec/config/karma/available_browsers.json +4957 -0
- package/spec/config/karma/config.ci.js +25 -0
- package/spec/config/karma/config.common.js +50 -0
- package/spec/config/karma/config.integration.js +26 -0
- package/spec/config/karma/config.unit.js +10 -0
- package/spec/config/karma/config.worker.js +34 -0
- package/spec/config/karma/integration.js +24 -0
- package/spec/config/karma/unit.js +20 -0
- package/spec/javascripts/helpers/mocks.js +274 -0
- package/spec/javascripts/helpers/node/integration.js +33 -0
- package/spec/javascripts/helpers/node/mock-dom-dependencies.ts +1 -0
- package/spec/javascripts/helpers/pusher_integration.js +1 -0
- package/spec/javascripts/helpers/pusher_integration_class.ts +12 -0
- package/spec/javascripts/helpers/timers/promises.js +9 -0
- package/spec/javascripts/helpers/waitsFor.js +37 -0
- package/spec/javascripts/helpers/web/integration.js +44 -0
- package/spec/javascripts/helpers/worker/mock-dom-dependencies.js +1 -0
- package/spec/javascripts/integration/core/cluster_config_spec.js +153 -0
- package/spec/javascripts/integration/core/falling_back_spec.js +195 -0
- package/spec/javascripts/integration/core/pusher_spec/index.js +68 -0
- package/spec/javascripts/integration/core/pusher_spec/test_builder.js +715 -0
- package/spec/javascripts/integration/core/timeout_configuration_spec.js +200 -0
- package/spec/javascripts/integration/core/transport_lists_spec.js +103 -0
- package/spec/javascripts/integration/index.node.js +12 -0
- package/spec/javascripts/integration/index.web.js +63 -0
- package/spec/javascripts/integration/index.worker.js +13 -0
- package/spec/javascripts/integration/web/dom/jsonp_spec.js +97 -0
- package/spec/javascripts/integration/web/dom/script_request_spec.js +90 -0
- package/spec/javascripts/polyfills/index.js +105 -0
- package/spec/javascripts/unit/core/channels/channel_spec.js +355 -0
- package/spec/javascripts/unit/core/channels/channels_spec.js +94 -0
- package/spec/javascripts/unit/core/channels/encrypted_channel_spec.js +343 -0
- package/spec/javascripts/unit/core/channels/presence_channel_spec.js +553 -0
- package/spec/javascripts/unit/core/channels/private_channel_spec.js +182 -0
- package/spec/javascripts/unit/core/config_spec.js +507 -0
- package/spec/javascripts/unit/core/connection/connection_manager_spec.js +656 -0
- package/spec/javascripts/unit/core/connection/connection_spec.js +286 -0
- package/spec/javascripts/unit/core/connection/handshake_spec.js +160 -0
- package/spec/javascripts/unit/core/connection/protocol_spec.js +420 -0
- package/spec/javascripts/unit/core/defaults_spec.js +26 -0
- package/spec/javascripts/unit/core/events_dispatcher_spec.js +385 -0
- package/spec/javascripts/unit/core/http/http_polling_socket_spec.js +60 -0
- package/spec/javascripts/unit/core/http/http_request_spec.js +185 -0
- package/spec/javascripts/unit/core/http/http_socket_spec.js +370 -0
- package/spec/javascripts/unit/core/http/http_streaming_socket_spec.js +56 -0
- package/spec/javascripts/unit/core/http/http_xhr_request_spec.js +164 -0
- package/spec/javascripts/unit/core/logger_spec.js +133 -0
- package/spec/javascripts/unit/core/pusher_spec.js +613 -0
- package/spec/javascripts/unit/core/pusher_with_encryption_spec.js +18 -0
- package/spec/javascripts/unit/core/strategies/best_connected_ever_strategy_spec.js +104 -0
- package/spec/javascripts/unit/core/strategies/delayed_strategy_spec.js +95 -0
- package/spec/javascripts/unit/core/strategies/first_connected_strategy_spec.js +68 -0
- package/spec/javascripts/unit/core/strategies/if_strategy_spec.js +165 -0
- package/spec/javascripts/unit/core/strategies/sequential_strategy_spec.js +213 -0
- package/spec/javascripts/unit/core/strategies/transport_strategy_spec.js +250 -0
- package/spec/javascripts/unit/core/strategies/websocket_prioritized_cached_strategy_spec.js +400 -0
- package/spec/javascripts/unit/core/timeline/timeline_spec.js +153 -0
- package/spec/javascripts/unit/core/transports/assistant_to_the_transport_manager_spec.js +223 -0
- package/spec/javascripts/unit/core/transports/hosts_and_ports_spec.js +85 -0
- package/spec/javascripts/unit/core/transports/transport_connection_spec.js +585 -0
- package/spec/javascripts/unit/core/transports/transport_manager_spec.js +64 -0
- package/spec/javascripts/unit/core/user_spec.js +303 -0
- package/spec/javascripts/unit/core/utils/periodic_timer_spec.js +74 -0
- package/spec/javascripts/unit/core/utils/timers_spec.js +157 -0
- package/spec/javascripts/unit/core/utils/url_store_spec.js +14 -0
- package/spec/javascripts/unit/core/watchlist_spec.js +48 -0
- package/spec/javascripts/unit/core_with_runtime/auth/channel_authorizer_spec.js +137 -0
- package/spec/javascripts/unit/core_with_runtime/auth/deprecated_channel_authorizer_spec.js +48 -0
- package/spec/javascripts/unit/core_with_runtime/auth/user_authorizer_spec.js +128 -0
- package/spec/javascripts/unit/core_with_runtime/readme.md +5 -0
- package/spec/javascripts/unit/index.node.js +11 -0
- package/spec/javascripts/unit/index.web.js +12 -0
- package/spec/javascripts/unit/index.worker.js +11 -0
- package/spec/javascripts/unit/isomorphic/transports/hosts_and_ports_spec.js +82 -0
- package/spec/javascripts/unit/isomorphic/transports/transports_spec.js +202 -0
- package/spec/javascripts/unit/node/timeline_sender_spec.js +83 -0
- package/spec/javascripts/unit/web/dom/dependency_loader_spec.js +249 -0
- package/spec/javascripts/unit/web/dom/jsonp_request_spec.js +130 -0
- package/spec/javascripts/unit/web/dom/script_receiver_factory_spec.js +68 -0
- package/spec/javascripts/unit/web/http/http_xdomain_request_spec.js +222 -0
- package/spec/javascripts/unit/web/pusher_authorizer_spec.js +64 -0
- package/spec/javascripts/unit/web/timeline/timeline_sender_spec.js +131 -0
- package/spec/javascripts/unit/web/transports/hosts_and_ports_spec.js +127 -0
- package/spec/javascripts/unit/web/transports/transports_spec.js +444 -0
- package/spec/javascripts/unit/worker/channel_authorizer_spec.js +156 -0
- package/spec/javascripts/unit/worker/timeline_sender_spec.js +76 -0
- package/src/core/auth/auth_transports.ts +18 -0
- package/src/core/auth/channel_authorizer.ts +64 -0
- package/src/core/auth/deprecated_channel_authorizer.ts +56 -0
- package/src/core/auth/options.ts +76 -0
- package/src/core/auth/user_authenticator.ts +62 -0
- package/src/core/base64.ts +49 -0
- package/src/core/channels/channel.ts +173 -0
- package/src/core/channels/channel_table.ts +7 -0
- package/src/core/channels/channels.ts +86 -0
- package/src/core/channels/encrypted_channel.ts +150 -0
- package/src/core/channels/filter.ts +342 -0
- package/src/core/channels/members.ts +80 -0
- package/src/core/channels/metadata.ts +5 -0
- package/src/core/channels/presence_channel.ts +113 -0
- package/src/core/channels/private_channel.ts +25 -0
- package/src/core/config.ts +189 -0
- package/src/core/connection/callbacks.ts +21 -0
- package/src/core/connection/connection.ts +160 -0
- package/src/core/connection/connection_manager.ts +371 -0
- package/src/core/connection/connection_manager_options.ts +14 -0
- package/src/core/connection/handshake/handshake_payload.ts +10 -0
- package/src/core/connection/handshake/index.ts +90 -0
- package/src/core/connection/protocol/action.ts +8 -0
- package/src/core/connection/protocol/message-types.ts +11 -0
- package/src/core/connection/protocol/protocol.ts +166 -0
- package/src/core/defaults.ts +66 -0
- package/src/core/delta/channel_state.ts +194 -0
- package/src/core/delta/decoders.ts +129 -0
- package/src/core/delta/index.ts +10 -0
- package/src/core/delta/manager.ts +504 -0
- package/src/core/delta/types.ts +60 -0
- package/src/core/errors.ts +69 -0
- package/src/core/events/callback.ts +6 -0
- package/src/core/events/callback_registry.ts +75 -0
- package/src/core/events/callback_table.ts +7 -0
- package/src/core/events/dispatcher.ts +84 -0
- package/src/core/http/ajax.ts +24 -0
- package/src/core/http/http_factory.ts +16 -0
- package/src/core/http/http_polling_socket.ts +24 -0
- package/src/core/http/http_request.ts +81 -0
- package/src/core/http/http_socket.ts +220 -0
- package/src/core/http/http_streaming_socket.ts +19 -0
- package/src/core/http/request_hooks.ts +9 -0
- package/src/core/http/socket_hooks.ts +11 -0
- package/src/core/http/state.ts +7 -0
- package/src/core/http/url_location.ts +6 -0
- package/src/core/logger.ts +66 -0
- package/src/core/options.ts +61 -0
- package/src/core/pusher-licence.js +7 -0
- package/src/core/pusher-with-encryption.js +1 -0
- package/src/core/pusher-with-encryption.ts +14 -0
- package/src/core/pusher.js +10 -0
- package/src/core/pusher.ts +412 -0
- package/src/core/reachability.ts +7 -0
- package/src/core/socket.ts +14 -0
- package/src/core/strategies/best_connected_ever_strategy.ts +81 -0
- package/src/core/strategies/delayed_strategy.ts +48 -0
- package/src/core/strategies/first_connected_strategy.ts +31 -0
- package/src/core/strategies/if_strategy.ts +34 -0
- package/src/core/strategies/sequential_strategy.ts +129 -0
- package/src/core/strategies/strategy.ts +8 -0
- package/src/core/strategies/strategy_builder.ts +67 -0
- package/src/core/strategies/strategy_options.ts +18 -0
- package/src/core/strategies/strategy_runner.ts +6 -0
- package/src/core/strategies/transport_strategy.ts +144 -0
- package/src/core/strategies/websocket_prioritized_cached_strategy.ts +157 -0
- package/src/core/timeline/level.ts +7 -0
- package/src/core/timeline/timeline.ts +90 -0
- package/src/core/timeline/timeline_sender.ts +33 -0
- package/src/core/timeline/timeline_transport.ts +11 -0
- package/src/core/transports/assistant_to_the_transport_manager.ts +104 -0
- package/src/core/transports/ping_delay_options.ts +7 -0
- package/src/core/transports/transport.ts +54 -0
- package/src/core/transports/transport_connection.ts +241 -0
- package/src/core/transports/transport_connection_options.ts +8 -0
- package/src/core/transports/transport_hooks.ts +16 -0
- package/src/core/transports/transport_manager.ts +52 -0
- package/src/core/transports/transports_table.ts +12 -0
- package/src/core/transports/url_scheme.ts +13 -0
- package/src/core/transports/url_schemes.ts +47 -0
- package/src/core/user.ts +186 -0
- package/src/core/util.ts +34 -0
- package/src/core/utils/collections.ts +353 -0
- package/src/core/utils/factory.ts +79 -0
- package/src/core/utils/flat_promise.ts +10 -0
- package/src/core/utils/timers/abstract_timer.ts +39 -0
- package/src/core/utils/timers/index.ts +39 -0
- package/src/core/utils/timers/scheduling.ts +11 -0
- package/src/core/utils/timers/timed_callback.ts +5 -0
- package/src/core/utils/url_store.ts +48 -0
- package/src/core/watchlist.ts +31 -0
- package/src/d.ts/constants/index.d.ts +5 -0
- package/src/d.ts/faye-websocket/faye-websocket.d.ts +21 -0
- package/src/d.ts/global/global.d.ts +1 -0
- package/src/d.ts/module/module.d.ts +12 -0
- package/src/d.ts/tweetnacl-util/index.d.ts +6 -0
- package/src/d.ts/window/events.d.ts +4 -0
- package/src/d.ts/window/sockjs.d.ts +3 -0
- package/src/d.ts/window/websocket.d.ts +4 -0
- package/src/d.ts/window/xmlhttprequest.d.ts +3 -0
- package/src/filter.ts +5 -0
- package/src/index.ts +8 -0
- package/src/runtimes/interface.ts +60 -0
- package/src/runtimes/isomorphic/auth/xhr_auth.ts +90 -0
- package/src/runtimes/isomorphic/default_strategy.ts +155 -0
- package/src/runtimes/isomorphic/http/http.ts +32 -0
- package/src/runtimes/isomorphic/http/http_xhr_request.ts +35 -0
- package/src/runtimes/isomorphic/runtime.ts +62 -0
- package/src/runtimes/isomorphic/timeline/xhr_timeline.ts +50 -0
- package/src/runtimes/isomorphic/transports/transport_connection_initializer.ts +19 -0
- package/src/runtimes/isomorphic/transports/transports.ts +83 -0
- package/src/runtimes/node/net_info.ts +10 -0
- package/src/runtimes/node/runtime.ts +68 -0
- package/src/runtimes/react-native/net_info.ts +42 -0
- package/src/runtimes/react-native/runtime.ts +65 -0
- package/src/runtimes/web/auth/jsonp_auth.ts +51 -0
- package/src/runtimes/web/browser.ts +24 -0
- package/src/runtimes/web/default_strategy.ts +201 -0
- package/src/runtimes/web/dom/dependencies.ts +16 -0
- package/src/runtimes/web/dom/dependency_loader.ts +93 -0
- package/src/runtimes/web/dom/json2.js +486 -0
- package/src/runtimes/web/dom/jsonp_request.ts +52 -0
- package/src/runtimes/web/dom/script_receiver.ts +8 -0
- package/src/runtimes/web/dom/script_receiver_factory.ts +57 -0
- package/src/runtimes/web/dom/script_request.ts +85 -0
- package/src/runtimes/web/http/http.ts +8 -0
- package/src/runtimes/web/http/http_xdomain_request.ts +37 -0
- package/src/runtimes/web/net_info.ts +50 -0
- package/src/runtimes/web/runtime.ts +174 -0
- package/src/runtimes/web/timeline/jsonp_timeline.ts +34 -0
- package/src/runtimes/web/transports/transport_connection_initializer.ts +39 -0
- package/src/runtimes/web/transports/transports.ts +67 -0
- package/src/runtimes/worker/auth/fetch_auth.ts +69 -0
- package/src/runtimes/worker/net_info.ts +10 -0
- package/src/runtimes/worker/runtime.ts +75 -0
- package/src/runtimes/worker/timeline/fetch_timeline.ts +39 -0
- package/tsconfig.json +18 -0
- package/types/spec/javascripts/helpers/node/mock-dom-dependencies.d.ts +1 -0
- package/types/spec/javascripts/helpers/pusher_integration_class.d.ts +4 -0
- package/types/src/core/auth/auth_transports.d.ts +9 -0
- package/types/src/core/auth/channel_authorizer.d.ts +3 -0
- package/types/src/core/auth/deprecated_channel_authorizer.d.ts +18 -0
- package/types/src/core/auth/options.d.ts +48 -0
- package/types/src/core/auth/user_authenticator.d.ts +3 -0
- package/types/src/core/base64.d.ts +1 -0
- package/types/src/core/channels/channel.d.ts +25 -0
- package/types/src/core/channels/channel_table.d.ts +5 -0
- package/types/src/core/channels/channels.d.ts +12 -0
- package/types/src/core/channels/encrypted_channel.d.ts +15 -0
- package/types/src/core/channels/filter.d.ts +33 -0
- package/types/src/core/channels/members.d.ts +14 -0
- package/types/src/core/channels/metadata.d.ts +4 -0
- package/types/src/core/channels/presence_channel.d.ts +13 -0
- package/types/src/core/channels/private_channel.d.ts +5 -0
- package/types/src/core/config.d.ts +31 -0
- package/types/src/core/connection/callbacks.d.ts +18 -0
- package/types/src/core/connection/connection.d.ts +16 -0
- package/types/src/core/connection/connection_manager.d.ts +50 -0
- package/types/src/core/connection/connection_manager_options.d.ts +11 -0
- package/types/src/core/connection/handshake/handshake_payload.d.ts +8 -0
- package/types/src/core/connection/handshake/index.d.ts +12 -0
- package/types/src/core/connection/protocol/action.d.ts +7 -0
- package/types/src/core/connection/protocol/message-types.d.ts +10 -0
- package/types/src/core/connection/protocol/protocol.d.ts +10 -0
- package/types/src/core/defaults.d.ts +26 -0
- package/types/src/core/delta/channel_state.d.ts +23 -0
- package/types/src/core/delta/decoders.d.ts +12 -0
- package/types/src/core/delta/index.d.ts +4 -0
- package/types/src/core/delta/manager.d.ts +27 -0
- package/types/src/core/delta/types.d.ts +50 -0
- package/types/src/core/errors.d.ts +28 -0
- package/types/src/core/events/callback.d.ts +5 -0
- package/types/src/core/events/callback_registry.d.ts +11 -0
- package/types/src/core/events/callback_table.d.ts +5 -0
- package/types/src/core/events/dispatcher.d.ts +14 -0
- package/types/src/core/http/ajax.d.ts +16 -0
- package/types/src/core/http/http_factory.d.ts +13 -0
- package/types/src/core/http/http_polling_socket.d.ts +3 -0
- package/types/src/core/http/http_request.d.ts +17 -0
- package/types/src/core/http/http_socket.d.ts +32 -0
- package/types/src/core/http/http_streaming_socket.d.ts +3 -0
- package/types/src/core/http/request_hooks.d.ts +6 -0
- package/types/src/core/http/socket_hooks.d.ts +8 -0
- package/types/src/core/http/state.d.ts +6 -0
- package/types/src/core/http/url_location.d.ts +5 -0
- package/types/src/core/logger.d.ts +11 -0
- package/types/src/core/options.d.ts +36 -0
- package/types/src/core/pusher-with-encryption.d.ts +5 -0
- package/types/src/core/pusher.d.ts +56 -0
- package/types/src/core/reachability.d.ts +5 -0
- package/types/src/core/socket.d.ts +12 -0
- package/types/src/core/strategies/best_connected_ever_strategy.d.ts +10 -0
- package/types/src/core/strategies/delayed_strategy.d.ts +15 -0
- package/types/src/core/strategies/first_connected_strategy.d.ts +8 -0
- package/types/src/core/strategies/if_strategy.d.ts +10 -0
- package/types/src/core/strategies/sequential_strategy.d.ts +16 -0
- package/types/src/core/strategies/strategy.d.ts +6 -0
- package/types/src/core/strategies/strategy_builder.d.ts +5 -0
- package/types/src/core/strategies/strategy_options.d.ts +16 -0
- package/types/src/core/strategies/strategy_runner.d.ts +5 -0
- package/types/src/core/strategies/transport_strategy.d.ts +15 -0
- package/types/src/core/strategies/websocket_prioritized_cached_strategy.d.ts +20 -0
- package/types/src/core/timeline/level.d.ts +6 -0
- package/types/src/core/timeline/timeline.d.ts +25 -0
- package/types/src/core/timeline/timeline_sender.d.ts +13 -0
- package/types/src/core/timeline/timeline_transport.d.ts +6 -0
- package/types/src/core/transports/assistant_to_the_transport_manager.d.ts +14 -0
- package/types/src/core/transports/ping_delay_options.d.ts +6 -0
- package/types/src/core/transports/transport.d.ts +8 -0
- package/types/src/core/transports/transport_connection.d.ts +35 -0
- package/types/src/core/transports/transport_connection_options.d.ts +6 -0
- package/types/src/core/transports/transport_hooks.d.ts +13 -0
- package/types/src/core/transports/transport_manager.d.ts +14 -0
- package/types/src/core/transports/transports_table.d.ts +10 -0
- package/types/src/core/transports/url_scheme.d.ts +11 -0
- package/types/src/core/transports/url_schemes.d.ts +4 -0
- package/types/src/core/user.d.ts +21 -0
- package/types/src/core/util.d.ts +8 -0
- package/types/src/core/utils/collections.d.ts +18 -0
- package/types/src/core/utils/factory.d.ts +29 -0
- package/types/src/core/utils/flat_promise.d.ts +6 -0
- package/types/src/core/utils/timers/abstract_timer.d.ts +10 -0
- package/types/src/core/utils/timers/index.d.ts +9 -0
- package/types/src/core/utils/timers/scheduling.d.ts +8 -0
- package/types/src/core/utils/timers/timed_callback.d.ts +4 -0
- package/types/src/core/utils/url_store.d.ts +4 -0
- package/types/src/core/watchlist.d.ts +8 -0
- package/types/src/runtimes/interface.d.ts +43 -0
- package/types/src/runtimes/isomorphic/auth/xhr_auth.d.ts +3 -0
- package/types/src/runtimes/isomorphic/default_strategy.d.ts +5 -0
- package/types/src/runtimes/isomorphic/http/http.d.ts +3 -0
- package/types/src/runtimes/isomorphic/http/http_xhr_request.d.ts +3 -0
- package/types/src/runtimes/isomorphic/runtime.d.ts +2 -0
- package/types/src/runtimes/isomorphic/timeline/xhr_timeline.d.ts +6 -0
- package/types/src/runtimes/isomorphic/transports/transport_connection_initializer.d.ts +1 -0
- package/types/src/runtimes/isomorphic/transports/transports.d.ts +5 -0
- package/types/src/runtimes/node/net_info.d.ts +6 -0
- package/types/src/runtimes/node/runtime.d.ts +3 -0
- package/types/src/runtimes/react-native/net_info.d.ts +8 -0
- package/types/src/runtimes/react-native/runtime.d.ts +3 -0
- package/types/src/runtimes/web/auth/jsonp_auth.d.ts +3 -0
- package/types/src/runtimes/web/browser.d.ts +19 -0
- package/types/src/runtimes/web/default_strategy.d.ts +5 -0
- package/types/src/runtimes/web/dom/dependencies.d.ts +4 -0
- package/types/src/runtimes/web/dom/dependency_loader.d.ts +10 -0
- package/types/src/runtimes/web/dom/jsonp_request.d.ts +10 -0
- package/types/src/runtimes/web/dom/script_receiver.d.ts +7 -0
- package/types/src/runtimes/web/dom/script_receiver_factory.d.ts +10 -0
- package/types/src/runtimes/web/dom/script_request.d.ts +9 -0
- package/types/src/runtimes/web/http/http.d.ts +2 -0
- package/types/src/runtimes/web/http/http_xdomain_request.d.ts +3 -0
- package/types/src/runtimes/web/net_info.d.ts +7 -0
- package/types/src/runtimes/web/runtime.d.ts +3 -0
- package/types/src/runtimes/web/timeline/jsonp_timeline.d.ts +6 -0
- package/types/src/runtimes/web/transports/transport_connection_initializer.d.ts +1 -0
- package/types/src/runtimes/web/transports/transports.d.ts +2 -0
- package/types/src/runtimes/worker/auth/fetch_auth.d.ts +3 -0
- package/types/src/runtimes/worker/net_info.d.ts +6 -0
- package/types/src/runtimes/worker/runtime.d.ts +3 -0
- package/types/src/runtimes/worker/timeline/fetch_timeline.d.ts +6 -0
- package/vite.config.js +52 -0
- package/vite.config.node.js +72 -0
- package/webpack/config.node.js +26 -0
- package/webpack/config.react-native.js +35 -0
- package/webpack/config.shared.js +50 -0
- package/webpack/config.web.js +36 -0
- package/webpack/config.worker.js +42 -0
- package/webpack/dev.server.js +17 -0
- package/webpack/hosting_config.js +6 -0
- package/with-encryption/index.d.ts +29 -0
- package/with-encryption/index.js +4 -0
- package/worker/index.d.ts +29 -0
- package/worker/index.js +1 -0
- package/worker/with-encryption/index.d.ts +29 -0
- 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)
|