@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,150 @@
|
|
|
1
|
+
import PrivateChannel from './private_channel';
|
|
2
|
+
import * as Errors from '../errors';
|
|
3
|
+
import Logger from '../logger';
|
|
4
|
+
import Pusher from '../pusher';
|
|
5
|
+
import { decode as encodeUTF8 } from '@stablelib/utf8';
|
|
6
|
+
import { decode as decodeBase64 } from '@stablelib/base64';
|
|
7
|
+
import Dispatcher from '../events/dispatcher';
|
|
8
|
+
import { PusherEvent } from '../connection/protocol/message-types';
|
|
9
|
+
import {
|
|
10
|
+
ChannelAuthorizationData,
|
|
11
|
+
ChannelAuthorizationCallback,
|
|
12
|
+
} from '../auth/options';
|
|
13
|
+
import * as nacl from 'tweetnacl';
|
|
14
|
+
|
|
15
|
+
/** Extends private channels to provide encrypted channel interface.
|
|
16
|
+
*
|
|
17
|
+
* @param {String} name
|
|
18
|
+
* @param {Pusher} pusher
|
|
19
|
+
*/
|
|
20
|
+
export default class EncryptedChannel extends PrivateChannel {
|
|
21
|
+
key: Uint8Array = null;
|
|
22
|
+
nacl: nacl;
|
|
23
|
+
|
|
24
|
+
constructor(name: string, pusher: Pusher, nacl: nacl) {
|
|
25
|
+
super(name, pusher);
|
|
26
|
+
this.nacl = nacl;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Authorizes the connection to use the channel.
|
|
30
|
+
*
|
|
31
|
+
* @param {String} socketId
|
|
32
|
+
* @param {Function} callback
|
|
33
|
+
*/
|
|
34
|
+
authorize(socketId: string, callback: ChannelAuthorizationCallback) {
|
|
35
|
+
super.authorize(
|
|
36
|
+
socketId,
|
|
37
|
+
(error: Error | null, authData: ChannelAuthorizationData) => {
|
|
38
|
+
if (error) {
|
|
39
|
+
callback(error, authData);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
let sharedSecret = authData['shared_secret'];
|
|
43
|
+
if (!sharedSecret) {
|
|
44
|
+
callback(
|
|
45
|
+
new Error(
|
|
46
|
+
`No shared_secret key in auth payload for encrypted channel: ${this.name}`,
|
|
47
|
+
),
|
|
48
|
+
null,
|
|
49
|
+
);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.key = decodeBase64(sharedSecret);
|
|
53
|
+
delete authData['shared_secret'];
|
|
54
|
+
callback(null, authData);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
trigger(event: string, data: any): boolean {
|
|
60
|
+
throw new Errors.UnsupportedFeature(
|
|
61
|
+
'Client events are not currently supported for encrypted channels',
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Handles an event. For internal use only.
|
|
66
|
+
*
|
|
67
|
+
* @param {PusherEvent} event
|
|
68
|
+
*/
|
|
69
|
+
handleEvent(event: PusherEvent) {
|
|
70
|
+
var eventName = event.event;
|
|
71
|
+
var data = event.data;
|
|
72
|
+
if (
|
|
73
|
+
eventName.indexOf('pusher_internal:') === 0 ||
|
|
74
|
+
eventName.indexOf('pusher:') === 0
|
|
75
|
+
) {
|
|
76
|
+
super.handleEvent(event);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.handleEncryptedEvent(eventName, data);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private handleEncryptedEvent(event: string, data: any): void {
|
|
83
|
+
if (!this.key) {
|
|
84
|
+
Logger.debug(
|
|
85
|
+
'Received encrypted event before key has been retrieved from the authEndpoint',
|
|
86
|
+
);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!data.ciphertext || !data.nonce) {
|
|
90
|
+
Logger.error(
|
|
91
|
+
'Unexpected format for encrypted event, expected object with `ciphertext` and `nonce` fields, got: ' +
|
|
92
|
+
data,
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let cipherText = decodeBase64(data.ciphertext);
|
|
97
|
+
if (cipherText.length < this.nacl.secretbox.overheadLength) {
|
|
98
|
+
Logger.error(
|
|
99
|
+
`Expected encrypted event ciphertext length to be ${this.nacl.secretbox.overheadLength}, got: ${cipherText.length}`,
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
let nonce = decodeBase64(data.nonce);
|
|
104
|
+
if (nonce.length < this.nacl.secretbox.nonceLength) {
|
|
105
|
+
Logger.error(
|
|
106
|
+
`Expected encrypted event nonce length to be ${this.nacl.secretbox.nonceLength}, got: ${nonce.length}`,
|
|
107
|
+
);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let bytes = this.nacl.secretbox.open(cipherText, nonce, this.key);
|
|
112
|
+
if (bytes === null) {
|
|
113
|
+
Logger.debug(
|
|
114
|
+
'Failed to decrypt an event, probably because it was encrypted with a different key. Fetching a new key from the authEndpoint...',
|
|
115
|
+
);
|
|
116
|
+
// Try a single time to retrieve a new auth key and decrypt the event with it
|
|
117
|
+
// If this fails, a new key will be requested when a new message is received
|
|
118
|
+
this.authorize(this.pusher.connection.socket_id, (error, authData) => {
|
|
119
|
+
if (error) {
|
|
120
|
+
Logger.error(
|
|
121
|
+
`Failed to make a request to the authEndpoint: ${authData}. Unable to fetch new key, so dropping encrypted event`,
|
|
122
|
+
);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
bytes = this.nacl.secretbox.open(cipherText, nonce, this.key);
|
|
126
|
+
if (bytes === null) {
|
|
127
|
+
Logger.error(
|
|
128
|
+
`Failed to decrypt event with new key. Dropping encrypted event`,
|
|
129
|
+
);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.emit(event, this.getDataToEmit(bytes));
|
|
133
|
+
return;
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this.emit(event, this.getDataToEmit(bytes));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Try and parse the decrypted bytes as JSON. If we can't parse it, just
|
|
141
|
+
// return the utf-8 string
|
|
142
|
+
getDataToEmit(bytes: Uint8Array): string {
|
|
143
|
+
let raw = encodeUTF8(bytes);
|
|
144
|
+
try {
|
|
145
|
+
return JSON.parse(raw);
|
|
146
|
+
} catch {
|
|
147
|
+
return raw;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
// sockudo-js/src/core/channels/filter.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Filter node structure for publication filtering by tags.
|
|
5
|
+
*
|
|
6
|
+
* This structure matches the server-side FilterNode format for zero-allocation
|
|
7
|
+
* evaluation during message broadcast.
|
|
8
|
+
*/
|
|
9
|
+
export interface FilterNode {
|
|
10
|
+
/** Logical operator: "and", "or", "not" (if present, this is a branch node) */
|
|
11
|
+
op?: string;
|
|
12
|
+
|
|
13
|
+
/** Key for comparison (leaf nodes only) */
|
|
14
|
+
key?: string;
|
|
15
|
+
|
|
16
|
+
/** Comparison operator: "eq", "neq", "in", "nin", "ex", "nex", "sw", "ew", "ct", "gt", "gte", "lt", "lte" */
|
|
17
|
+
cmp?: string;
|
|
18
|
+
|
|
19
|
+
/** Single value for most comparisons */
|
|
20
|
+
val?: string;
|
|
21
|
+
|
|
22
|
+
/** Multiple values for set operations (in, nin) */
|
|
23
|
+
vals?: string[];
|
|
24
|
+
|
|
25
|
+
/** Child nodes for logical operations */
|
|
26
|
+
nodes?: FilterNode[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Builder for constructing filter nodes programmatically.
|
|
31
|
+
*
|
|
32
|
+
* Provides a clean API for creating complex filters without dealing with
|
|
33
|
+
* the internal FilterNode structure directly.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Simple equality filter
|
|
38
|
+
* const filter = Filter.eq("event_type", "goal");
|
|
39
|
+
*
|
|
40
|
+
* // Complex nested filter
|
|
41
|
+
* const filter = Filter.or(
|
|
42
|
+
* Filter.eq("event_type", "goal"),
|
|
43
|
+
* Filter.and(
|
|
44
|
+
* Filter.eq("event_type", "shot"),
|
|
45
|
+
* Filter.gte("xG", "0.8")
|
|
46
|
+
* )
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export const Filter = {
|
|
51
|
+
// Comparison operators
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates an equality comparison: key == val
|
|
55
|
+
* @param key The tag key to compare
|
|
56
|
+
* @param val The value to compare against
|
|
57
|
+
* @returns FilterNode for equality comparison
|
|
58
|
+
*/
|
|
59
|
+
eq: (key: string, val: string): FilterNode => ({
|
|
60
|
+
key,
|
|
61
|
+
cmp: "eq",
|
|
62
|
+
val
|
|
63
|
+
}),
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates an inequality comparison: key != val
|
|
67
|
+
* @param key The tag key to compare
|
|
68
|
+
* @param val The value to compare against
|
|
69
|
+
* @returns FilterNode for inequality comparison
|
|
70
|
+
*/
|
|
71
|
+
neq: (key: string, val: string): FilterNode => ({
|
|
72
|
+
key,
|
|
73
|
+
cmp: "neq",
|
|
74
|
+
val
|
|
75
|
+
}),
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a set membership comparison: key in [vals...]
|
|
79
|
+
* @param key The tag key to compare
|
|
80
|
+
* @param vals Array of values for set membership
|
|
81
|
+
* @returns FilterNode for set membership comparison
|
|
82
|
+
*/
|
|
83
|
+
in: (key: string, vals: string[]): FilterNode => ({
|
|
84
|
+
key,
|
|
85
|
+
cmp: "in",
|
|
86
|
+
vals
|
|
87
|
+
}),
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Creates a set non-membership comparison: key not in [vals...]
|
|
91
|
+
* @param key The tag key to compare
|
|
92
|
+
* @param vals Array of values for set non-membership
|
|
93
|
+
* @returns FilterNode for set non-membership comparison
|
|
94
|
+
*/
|
|
95
|
+
nin: (key: string, vals: string[]): FilterNode => ({
|
|
96
|
+
key,
|
|
97
|
+
cmp: "nin",
|
|
98
|
+
vals
|
|
99
|
+
}),
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates an existence check: key exists
|
|
103
|
+
* @param key The tag key to check for existence
|
|
104
|
+
* @returns FilterNode for existence check
|
|
105
|
+
*/
|
|
106
|
+
exists: (key: string): FilterNode => ({
|
|
107
|
+
key,
|
|
108
|
+
cmp: "ex"
|
|
109
|
+
}),
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Creates a non-existence check: key does not exist
|
|
113
|
+
* @param key The tag key to check for non-existence
|
|
114
|
+
* @returns FilterNode for non-existence check
|
|
115
|
+
*/
|
|
116
|
+
notExists: (key: string): FilterNode => ({
|
|
117
|
+
key,
|
|
118
|
+
cmp: "nex"
|
|
119
|
+
}),
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Creates a starts-with comparison: key starts with val
|
|
123
|
+
* @param key The tag key to compare
|
|
124
|
+
* @param val The prefix to match
|
|
125
|
+
* @returns FilterNode for starts-with comparison
|
|
126
|
+
*/
|
|
127
|
+
startsWith: (key: string, val: string): FilterNode => ({
|
|
128
|
+
key,
|
|
129
|
+
cmp: "sw",
|
|
130
|
+
val
|
|
131
|
+
}),
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Creates an ends-with comparison: key ends with val
|
|
135
|
+
* @param key The tag key to compare
|
|
136
|
+
* @param val The suffix to match
|
|
137
|
+
* @returns FilterNode for ends-with comparison
|
|
138
|
+
*/
|
|
139
|
+
endsWith: (key: string, val: string): FilterNode => ({
|
|
140
|
+
key,
|
|
141
|
+
cmp: "ew",
|
|
142
|
+
val
|
|
143
|
+
}),
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates a contains comparison: key contains val
|
|
147
|
+
* @param key The tag key to compare
|
|
148
|
+
* @param val The substring to match
|
|
149
|
+
* @returns FilterNode for contains comparison
|
|
150
|
+
*/
|
|
151
|
+
contains: (key: string, val: string): FilterNode => ({
|
|
152
|
+
key,
|
|
153
|
+
cmp: "ct",
|
|
154
|
+
val
|
|
155
|
+
}),
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Creates a greater-than comparison: key > val (numeric)
|
|
159
|
+
* @param key The tag key to compare
|
|
160
|
+
* @param val The numeric value to compare against (as string)
|
|
161
|
+
* @returns FilterNode for greater-than comparison
|
|
162
|
+
*/
|
|
163
|
+
gt: (key: string, val: string): FilterNode => ({
|
|
164
|
+
key,
|
|
165
|
+
cmp: "gt",
|
|
166
|
+
val
|
|
167
|
+
}),
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Creates a greater-than-or-equal comparison: key >= val (numeric)
|
|
171
|
+
* @param key The tag key to compare
|
|
172
|
+
* @param val The numeric value to compare against (as string)
|
|
173
|
+
* @returns FilterNode for greater-than-or-equal comparison
|
|
174
|
+
*/
|
|
175
|
+
gte: (key: string, val: string): FilterNode => ({
|
|
176
|
+
key,
|
|
177
|
+
cmp: "gte",
|
|
178
|
+
val
|
|
179
|
+
}),
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Creates a less-than comparison: key < val (numeric)
|
|
183
|
+
* @param key The tag key to compare
|
|
184
|
+
* @param val The numeric value to compare against (as string)
|
|
185
|
+
* @returns FilterNode for less-than comparison
|
|
186
|
+
*/
|
|
187
|
+
lt: (key: string, val: string): FilterNode => ({
|
|
188
|
+
key,
|
|
189
|
+
cmp: "lt",
|
|
190
|
+
val
|
|
191
|
+
}),
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Creates a less-than-or-equal comparison: key <= val (numeric)
|
|
195
|
+
* @param key The tag key to compare
|
|
196
|
+
* @param val The numeric value to compare against (as string)
|
|
197
|
+
* @returns FilterNode for less-than-or-equal comparison
|
|
198
|
+
*/
|
|
199
|
+
lte: (key: string, val: string): FilterNode => ({
|
|
200
|
+
key,
|
|
201
|
+
cmp: "lte",
|
|
202
|
+
val
|
|
203
|
+
}),
|
|
204
|
+
|
|
205
|
+
// Logical operators
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Creates an AND logical operation: all children must match
|
|
209
|
+
* @param nodes Child filter nodes to combine with AND
|
|
210
|
+
* @returns FilterNode for AND operation
|
|
211
|
+
*/
|
|
212
|
+
and: (...nodes: FilterNode[]): FilterNode => ({
|
|
213
|
+
op: "and",
|
|
214
|
+
nodes
|
|
215
|
+
}),
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Creates an OR logical operation: at least one child must match
|
|
219
|
+
* @param nodes Child filter nodes to combine with OR
|
|
220
|
+
* @returns FilterNode for OR operation
|
|
221
|
+
*/
|
|
222
|
+
or: (...nodes: FilterNode[]): FilterNode => ({
|
|
223
|
+
op: "or",
|
|
224
|
+
nodes
|
|
225
|
+
}),
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Creates a NOT logical operation: negates the child
|
|
229
|
+
* @param node Child filter node to negate
|
|
230
|
+
* @returns FilterNode for NOT operation
|
|
231
|
+
*/
|
|
232
|
+
not: (node: FilterNode): FilterNode => ({
|
|
233
|
+
op: "not",
|
|
234
|
+
nodes: [node]
|
|
235
|
+
})
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Validates a filter node structure.
|
|
240
|
+
*
|
|
241
|
+
* @param filter The filter node to validate
|
|
242
|
+
* @returns Error message if invalid, null if valid
|
|
243
|
+
*/
|
|
244
|
+
export function validateFilter(filter: FilterNode): string | null {
|
|
245
|
+
if (filter.op) {
|
|
246
|
+
// Branch node - logical operation
|
|
247
|
+
const op = filter.op;
|
|
248
|
+
|
|
249
|
+
if (!["and", "or", "not"].includes(op)) {
|
|
250
|
+
return `Invalid logical operator: ${op}`;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (!filter.nodes || !Array.isArray(filter.nodes)) {
|
|
254
|
+
return `Logical operation '${op}' requires nodes array`;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (op === "not" && filter.nodes.length !== 1) {
|
|
258
|
+
return `NOT operation requires exactly one child node, got ${filter.nodes.length}`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if ((op === "and" || op === "or") && filter.nodes.length === 0) {
|
|
262
|
+
return `${op.toUpperCase()} operation requires at least one child node`;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Validate all children recursively
|
|
266
|
+
for (let i = 0; i < filter.nodes.length; i++) {
|
|
267
|
+
const childError = validateFilter(filter.nodes[i]);
|
|
268
|
+
if (childError) {
|
|
269
|
+
return `Child node ${i}: ${childError}`;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
} else {
|
|
273
|
+
// Leaf node - comparison
|
|
274
|
+
if (!filter.key) {
|
|
275
|
+
return "Leaf node requires a key";
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (!filter.cmp) {
|
|
279
|
+
return "Leaf node requires a comparison operator";
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const validOps = ["eq", "neq", "in", "nin", "ex", "nex", "sw", "ew", "ct", "gt", "gte", "lt", "lte"];
|
|
283
|
+
if (!validOps.includes(filter.cmp)) {
|
|
284
|
+
return `Invalid comparison operator: ${filter.cmp}`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Check value requirements based on operator
|
|
288
|
+
if (filter.cmp === "in" || filter.cmp === "nin") {
|
|
289
|
+
if (!filter.vals || !Array.isArray(filter.vals) || filter.vals.length === 0) {
|
|
290
|
+
return `${filter.cmp} operation requires non-empty vals array`;
|
|
291
|
+
}
|
|
292
|
+
} else if (filter.cmp === "ex" || filter.cmp === "nex") {
|
|
293
|
+
// Existence checks don't need values
|
|
294
|
+
} else {
|
|
295
|
+
if (!filter.val) {
|
|
296
|
+
return `${filter.cmp} operation requires a val`;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Example filter patterns for common use cases
|
|
306
|
+
*/
|
|
307
|
+
export const FilterExamples = {
|
|
308
|
+
/**
|
|
309
|
+
* Filter for a specific event type
|
|
310
|
+
* @example Filter.eq("event_type", "goal")
|
|
311
|
+
*/
|
|
312
|
+
eventType: (type: string) => Filter.eq("event_type", type),
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Filter for events in a set of types
|
|
316
|
+
* @example FilterExamples.eventTypes(["goal", "shot"])
|
|
317
|
+
*/
|
|
318
|
+
eventTypes: (types: string[]) => Filter.in("event_type", types),
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Filter for numeric range
|
|
322
|
+
* @example FilterExamples.range("xG", "0.5", "0.9")
|
|
323
|
+
*/
|
|
324
|
+
range: (key: string, min: string, max: string) =>
|
|
325
|
+
Filter.and(
|
|
326
|
+
Filter.gte(key, min),
|
|
327
|
+
Filter.lte(key, max)
|
|
328
|
+
),
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Filter for goals OR high-probability shots
|
|
332
|
+
* @example FilterExamples.importantEvents("0.8")
|
|
333
|
+
*/
|
|
334
|
+
importantEvents: (xGThreshold: string) =>
|
|
335
|
+
Filter.or(
|
|
336
|
+
Filter.eq("event_type", "goal"),
|
|
337
|
+
Filter.and(
|
|
338
|
+
Filter.eq("event_type", "shot"),
|
|
339
|
+
Filter.gte("xG", xGThreshold)
|
|
340
|
+
)
|
|
341
|
+
)
|
|
342
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as Collections from '../utils/collections';
|
|
2
|
+
|
|
3
|
+
/** Represents a collection of members of a presence channel. */
|
|
4
|
+
export default class Members {
|
|
5
|
+
members: any;
|
|
6
|
+
count: number;
|
|
7
|
+
myID: any;
|
|
8
|
+
me: any;
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
this.reset();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Returns member's info for given id.
|
|
15
|
+
*
|
|
16
|
+
* Resulting object containts two fields - id and info.
|
|
17
|
+
*
|
|
18
|
+
* @param {Number} id
|
|
19
|
+
* @return {Object} member's info or null
|
|
20
|
+
*/
|
|
21
|
+
get(id: string): any {
|
|
22
|
+
if (Object.prototype.hasOwnProperty.call(this.members, id)) {
|
|
23
|
+
return {
|
|
24
|
+
id: id,
|
|
25
|
+
info: this.members[id],
|
|
26
|
+
};
|
|
27
|
+
} else {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Calls back for each member in unspecified order.
|
|
33
|
+
*
|
|
34
|
+
* @param {Function} callback
|
|
35
|
+
*/
|
|
36
|
+
each(callback: Function) {
|
|
37
|
+
Collections.objectApply(this.members, (member, id) => {
|
|
38
|
+
callback(this.get(id));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Updates the id for connected member. For internal use only. */
|
|
43
|
+
setMyID(id: string) {
|
|
44
|
+
this.myID = id;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Handles subscription data. For internal use only. */
|
|
48
|
+
onSubscription(subscriptionData: any) {
|
|
49
|
+
this.members = subscriptionData.presence.hash;
|
|
50
|
+
this.count = subscriptionData.presence.count;
|
|
51
|
+
this.me = this.get(this.myID);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Adds a new member to the collection. For internal use only. */
|
|
55
|
+
addMember(memberData: any) {
|
|
56
|
+
if (this.get(memberData.user_id) === null) {
|
|
57
|
+
this.count++;
|
|
58
|
+
}
|
|
59
|
+
this.members[memberData.user_id] = memberData.user_info;
|
|
60
|
+
return this.get(memberData.user_id);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Adds a member from the collection. For internal use only. */
|
|
64
|
+
removeMember(memberData: any) {
|
|
65
|
+
var member = this.get(memberData.user_id);
|
|
66
|
+
if (member) {
|
|
67
|
+
delete this.members[memberData.user_id];
|
|
68
|
+
this.count--;
|
|
69
|
+
}
|
|
70
|
+
return member;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Resets the collection to the initial state. For internal use only. */
|
|
74
|
+
reset() {
|
|
75
|
+
this.members = {};
|
|
76
|
+
this.count = 0;
|
|
77
|
+
this.myID = null;
|
|
78
|
+
this.me = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import PrivateChannel from './private_channel';
|
|
2
|
+
import Logger from '../logger';
|
|
3
|
+
import Members from './members';
|
|
4
|
+
import Pusher from '../pusher';
|
|
5
|
+
import UrlStore from 'core/utils/url_store';
|
|
6
|
+
import { PusherEvent } from '../connection/protocol/message-types';
|
|
7
|
+
import Metadata from './metadata';
|
|
8
|
+
import { ChannelAuthorizationData } from '../auth/options';
|
|
9
|
+
|
|
10
|
+
export default class PresenceChannel extends PrivateChannel {
|
|
11
|
+
members: Members;
|
|
12
|
+
|
|
13
|
+
/** Adds presence channel functionality to private channels.
|
|
14
|
+
*
|
|
15
|
+
* @param {String} name
|
|
16
|
+
* @param {Pusher} pusher
|
|
17
|
+
*/
|
|
18
|
+
constructor(name: string, pusher: Pusher) {
|
|
19
|
+
super(name, pusher);
|
|
20
|
+
this.members = new Members();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Authorizes the connection as a member of the channel.
|
|
24
|
+
*
|
|
25
|
+
* @param {String} socketId
|
|
26
|
+
* @param {Function} callback
|
|
27
|
+
*/
|
|
28
|
+
authorize(socketId: string, callback: Function) {
|
|
29
|
+
super.authorize(socketId, async (error, authData) => {
|
|
30
|
+
if (!error) {
|
|
31
|
+
authData = authData as ChannelAuthorizationData;
|
|
32
|
+
if (authData.channel_data != null) {
|
|
33
|
+
var channelData = JSON.parse(authData.channel_data);
|
|
34
|
+
this.members.setMyID(channelData.user_id);
|
|
35
|
+
} else {
|
|
36
|
+
await this.pusher.user.signinDonePromise;
|
|
37
|
+
if (this.pusher.user.user_data != null) {
|
|
38
|
+
// If the user is signed in, get the id of the authenticated user
|
|
39
|
+
// and allow the presence authorization to continue.
|
|
40
|
+
this.members.setMyID(this.pusher.user.user_data.id);
|
|
41
|
+
} else {
|
|
42
|
+
let suffix = UrlStore.buildLogSuffix('authorizationEndpoint');
|
|
43
|
+
Logger.error(
|
|
44
|
+
`Invalid auth response for channel '${this.name}', ` +
|
|
45
|
+
`expected 'channel_data' field. ${suffix}, ` +
|
|
46
|
+
`or the user should be signed in.`,
|
|
47
|
+
);
|
|
48
|
+
callback('Invalid auth response');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
callback(error, authData);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Handles presence and subscription events. For internal use only.
|
|
58
|
+
*
|
|
59
|
+
* @param {PusherEvent} event
|
|
60
|
+
*/
|
|
61
|
+
handleEvent(event: PusherEvent) {
|
|
62
|
+
var eventName = event.event;
|
|
63
|
+
if (eventName.indexOf('pusher_internal:') === 0) {
|
|
64
|
+
this.handleInternalEvent(event);
|
|
65
|
+
} else {
|
|
66
|
+
var data = event.data;
|
|
67
|
+
var metadata: Metadata = {};
|
|
68
|
+
if (event.user_id) {
|
|
69
|
+
metadata.user_id = event.user_id;
|
|
70
|
+
}
|
|
71
|
+
this.emit(eventName, data, metadata);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
handleInternalEvent(event: PusherEvent) {
|
|
75
|
+
var eventName = event.event;
|
|
76
|
+
var data = event.data;
|
|
77
|
+
switch (eventName) {
|
|
78
|
+
case 'pusher_internal:subscription_succeeded':
|
|
79
|
+
this.handleSubscriptionSucceededEvent(event);
|
|
80
|
+
break;
|
|
81
|
+
case 'pusher_internal:subscription_count':
|
|
82
|
+
this.handleSubscriptionCountEvent(event);
|
|
83
|
+
break;
|
|
84
|
+
case 'pusher_internal:member_added':
|
|
85
|
+
var addedMember = this.members.addMember(data);
|
|
86
|
+
this.emit('pusher:member_added', addedMember);
|
|
87
|
+
break;
|
|
88
|
+
case 'pusher_internal:member_removed':
|
|
89
|
+
var removedMember = this.members.removeMember(data);
|
|
90
|
+
if (removedMember) {
|
|
91
|
+
this.emit('pusher:member_removed', removedMember);
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
handleSubscriptionSucceededEvent(event: PusherEvent) {
|
|
98
|
+
this.subscriptionPending = false;
|
|
99
|
+
this.subscribed = true;
|
|
100
|
+
if (this.subscriptionCancelled) {
|
|
101
|
+
this.pusher.unsubscribe(this.name);
|
|
102
|
+
} else {
|
|
103
|
+
this.members.onSubscription(event.data);
|
|
104
|
+
this.emit('pusher:subscription_succeeded', this.members);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Resets the channel state, including members map. For internal use only. */
|
|
109
|
+
disconnect() {
|
|
110
|
+
this.members.reset();
|
|
111
|
+
super.disconnect();
|
|
112
|
+
}
|
|
113
|
+
}
|