@cratis/arc 22.0.2 → 22.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/queries/ObservableQueryFor.js +6 -1
- package/dist/cjs/queries/ObservableQueryFor.js.map +1 -1
- package/dist/cjs/queries/QueryInstanceCache.js +6 -6
- package/dist/cjs/queries/QueryInstanceCache.js.map +1 -1
- package/dist/cjs/queries/QueryResult.js +23 -4
- package/dist/cjs/queries/QueryResult.js.map +1 -1
- package/dist/cjs/queries/QueryResultWithState.js +20 -7
- package/dist/cjs/queries/QueryResultWithState.js.map +1 -1
- package/dist/cjs/queries/ServerSentEventHubConnection.js +120 -58
- package/dist/cjs/queries/ServerSentEventHubConnection.js.map +1 -1
- package/dist/cjs/queries/WebSocketHubConnection.js +121 -51
- package/dist/cjs/queries/WebSocketHubConnection.js.map +1 -1
- package/dist/esm/queries/IQueryResult.d.ts +1 -0
- package/dist/esm/queries/IQueryResult.d.ts.map +1 -1
- package/dist/esm/queries/ObservableQueryFor.d.ts.map +1 -1
- package/dist/esm/queries/ObservableQueryFor.js +6 -1
- package/dist/esm/queries/ObservableQueryFor.js.map +1 -1
- package/dist/esm/queries/QueryInstanceCache.d.ts +1 -1
- package/dist/esm/queries/QueryInstanceCache.d.ts.map +1 -1
- package/dist/esm/queries/QueryInstanceCache.js +6 -6
- package/dist/esm/queries/QueryInstanceCache.js.map +1 -1
- package/dist/esm/queries/QueryResult.d.ts +2 -0
- package/dist/esm/queries/QueryResult.d.ts.map +1 -1
- package/dist/esm/queries/QueryResult.js +23 -4
- package/dist/esm/queries/QueryResult.js.map +1 -1
- package/dist/esm/queries/QueryResultWithState.d.ts +3 -3
- package/dist/esm/queries/QueryResultWithState.d.ts.map +1 -1
- package/dist/esm/queries/QueryResultWithState.js +20 -7
- package/dist/esm/queries/QueryResultWithState.js.map +1 -1
- package/dist/esm/queries/ServerSentEventHubConnection.d.ts +11 -4
- package/dist/esm/queries/ServerSentEventHubConnection.d.ts.map +1 -1
- package/dist/esm/queries/ServerSentEventHubConnection.js +120 -58
- package/dist/esm/queries/ServerSentEventHubConnection.js.map +1 -1
- package/dist/esm/queries/WebSocketHubConnection.d.ts +13 -2
- package/dist/esm/queries/WebSocketHubConnection.d.ts.map +1 -1
- package/dist/esm/queries/WebSocketHubConnection.js +121 -51
- package/dist/esm/queries/WebSocketHubConnection.js.map +1 -1
- package/dist/esm/queries/for_ObservableQueryFor/when_performing/with_a_not_ready_result.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_performing/with_a_not_ready_result.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_performing/with_a_not_ready_result.js +34 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_performing/with_a_not_ready_result.js.map +1 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_direct_mode_and_sse_transport.js +26 -2
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_direct_mode_and_sse_transport.js.map +1 -1
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_direct_mode_disabled_and_sse_transport.js +60 -3
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_direct_mode_disabled_and_sse_transport.js.map +1 -1
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_web_socket_hub_payload_without_readiness.d.ts +2 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_web_socket_hub_payload_without_readiness.d.ts.map +1 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_web_socket_hub_payload_without_readiness.js +83 -0
- package/dist/esm/queries/for_ObservableQueryFor/when_subscribing/with_web_socket_hub_payload_without_readiness.js.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_only_readiness_changed.d.ts +2 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_only_readiness_changed.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_only_readiness_changed.js +22 -0
- package/dist/esm/queries/for_QueryInstanceCache/when_setting_last_result/with_only_readiness_changed.js.map +1 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/with_readiness_false.d.ts +2 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/with_readiness_false.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/with_readiness_false.js +17 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/with_readiness_false.js.map +1 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/without_readiness.d.ts +2 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/without_readiness.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/without_readiness.js +16 -0
- package/dist/esm/queries/for_QueryResult/when_constructing_from_a_server_result/without_readiness.js.map +1 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/with_readiness_false.d.ts +2 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/with_readiness_false.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/with_readiness_false.js +19 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/with_readiness_false.js.map +1 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/without_readiness.d.ts +2 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/without_readiness.d.ts.map +1 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/without_readiness.js +19 -0
- package/dist/esm/queries/for_QueryResultWithState/when_creating_from_query_result/without_readiness.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_deferred_promise.d.ts +7 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_deferred_promise.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_deferred_promise.js +12 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_deferred_promise.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_server_sent_event_hub_connection.d.ts +2 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_server_sent_event_hub_connection.d.ts.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_server_sent_event_hub_connection.js +15 -4
- package/dist/esm/queries/for_ServerSentEventHubConnection/given/a_server_sent_event_hub_connection.js.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_a_retired_event_source_fires/ignores_connected_and_error_callbacks.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_a_retired_event_source_fires/ignores_connected_and_error_callbacks.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_a_retired_event_source_fires/ignores_connected_and_error_callbacks.js +44 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_a_retired_event_source_fires/ignores_connected_and_error_callbacks.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_replaced.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_replaced.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_replaced.js +74 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_replaced.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_unsubscribed.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_unsubscribed.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_unsubscribed.js +74 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_unsubscribed.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_is_rejected.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_is_rejected.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_is_rejected.js +59 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_is_rejected.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_returns_non_ok.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_returns_non_ok.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_returns_non_ok.js +58 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_returns_non_ok.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_disposing/cleans_up_resources.js +6 -3
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_disposing/cleans_up_resources.js.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_receiving_unauthorized/notifies_subscriber_and_removes_subscription.js +23 -6
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_receiving_unauthorized/notifies_subscriber_and_removes_subscription.js.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_reconnecting/after_error.js +20 -5
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_reconnecting/after_error.js.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_reconnecting/and_an_immediate_open_wins_the_backoff_race.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_reconnecting/and_an_immediate_open_wins_the_backoff_race.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_reconnecting/and_an_immediate_open_wins_the_backoff_race.js +20 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_reconnecting/and_an_immediate_open_wins_the_backoff_race.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_replacing_a_subscription/ignores_messages_from_the_retired_generation.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_replacing_a_subscription/ignores_messages_from_the_retired_generation.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_replacing_a_subscription/ignores_messages_from_the_retired_generation.js +68 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_replacing_a_subscription/ignores_messages_from_the_retired_generation.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscribing/sends_subscribe_post.js +38 -13
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscribing/sends_subscribe_post.js.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscription_revisions_are_not_advertised/uses_legacy_protocol.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscription_revisions_are_not_advertised/uses_legacy_protocol.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscription_revisions_are_not_advertised/uses_legacy_protocol.js +54 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscription_revisions_are_not_advertised/uses_legacy_protocol.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_unsubscribing/the_only_query.js +18 -4
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_unsubscribing/the_only_query.js.map +1 -1
- package/dist/esm/queries/for_WebSocketHubConnection/when_receiving_unauthorized/notifies_subscriber_and_removes_subscription.js +22 -5
- package/dist/esm/queries/for_WebSocketHubConnection/when_receiving_unauthorized/notifies_subscriber_and_removes_subscription.js.map +1 -1
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/ignores_a_pending_reconnect_and_stale_socket_callbacks.d.ts +2 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/ignores_a_pending_reconnect_and_stale_socket_callbacks.d.ts.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/ignores_a_pending_reconnect_and_stale_socket_callbacks.js +108 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/ignores_a_pending_reconnect_and_stale_socket_callbacks.js.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/replaces_a_closing_socket_safely.d.ts +2 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/replaces_a_closing_socket_safely.d.ts.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/replaces_a_closing_socket_safely.js +33 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/replaces_a_closing_socket_safely.js.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/resubscribes_all_queries.js +26 -4
- package/dist/esm/queries/for_WebSocketHubConnection/when_reconnecting/resubscribes_all_queries.js.map +1 -1
- package/dist/esm/queries/for_WebSocketHubConnection/when_replacing_a_subscription/ignores_stale_result_unauthorized_and_error.d.ts +2 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_replacing_a_subscription/ignores_stale_result_unauthorized_and_error.d.ts.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_replacing_a_subscription/ignores_stale_result_unauthorized_and_error.js +62 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_replacing_a_subscription/ignores_stale_result_unauthorized_and_error.js.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_subscribing/to_a_query.js +18 -5
- package/dist/esm/queries/for_WebSocketHubConnection/when_subscribing/to_a_query.js.map +1 -1
- package/dist/esm/queries/for_WebSocketHubConnection/when_subscription_revisions_are_supported/upgrades_active_subscriptions_to_strict_mode.d.ts +2 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_subscription_revisions_are_supported/upgrades_active_subscriptions_to_strict_mode.d.ts.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_subscription_revisions_are_supported/upgrades_active_subscriptions_to_strict_mode.js +56 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_subscription_revisions_are_supported/upgrades_active_subscriptions_to_strict_mode.js.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_unsubscribing/the_only_query.js +16 -3
- package/dist/esm/queries/for_WebSocketHubConnection/when_unsubscribing/the_only_query.js.map +1 -1
- package/dist/esm/queries/for_WebSocketHubConnection/when_unsubscribing/with_revision_support_not_advertised.d.ts +2 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_unsubscribing/with_revision_support_not_advertised.d.ts.map +1 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_unsubscribing/with_revision_support_not_advertised.js +33 -0
- package/dist/esm/queries/for_WebSocketHubConnection/when_unsubscribing/with_revision_support_not_advertised.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/queries/IQueryResult.ts +10 -0
- package/queries/ObservableQueryFor.ts +44 -16
- package/queries/QueryInstanceCache.ts +42 -19
- package/queries/QueryResult.ts +145 -79
- package/queries/QueryResultWithState.ts +32 -9
- package/queries/ServerSentEventHubConnection.ts +270 -83
- package/queries/WebSocketHubConnection.ts +188 -56
- package/queries/for_ObservableQueryFor/when_performing/with_a_not_ready_result.ts +46 -0
- package/queries/for_ObservableQueryFor/when_subscribing/with_direct_mode_and_sse_transport.ts +91 -57
- package/queries/for_ObservableQueryFor/when_subscribing/with_direct_mode_disabled_and_sse_transport.ts +125 -53
- package/queries/for_ObservableQueryFor/when_subscribing/with_web_socket_hub_payload_without_readiness.ts +107 -0
- package/queries/for_QueryInstanceCache/when_setting_last_result/with_only_readiness_changed.ts +63 -0
- package/queries/for_QueryResult/when_constructing_from_a_server_result/with_readiness_false.ts +25 -0
- package/queries/for_QueryResult/when_constructing_from_a_server_result/without_readiness.ts +24 -0
- package/queries/for_QueryResultWithState/when_creating_from_query_result/with_readiness_false.ts +28 -0
- package/queries/for_QueryResultWithState/when_creating_from_query_result/without_readiness.ts +25 -0
- package/queries/for_ServerSentEventHubConnection/given/a_deferred_promise.ts +15 -0
- package/queries/for_ServerSentEventHubConnection/given/a_server_sent_event_hub_connection.ts +18 -7
- package/queries/for_ServerSentEventHubConnection/when_a_retired_event_source_fires/ignores_connected_and_error_callbacks.ts +59 -0
- package/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_replaced.ts +113 -0
- package/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_query_is_unsubscribed.ts +109 -0
- package/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_is_rejected.ts +81 -0
- package/queries/for_ServerSentEventHubConnection/when_connection_changes_while_subscribe_is_in_flight/and_the_stale_request_returns_non_ok.ts +83 -0
- package/queries/for_ServerSentEventHubConnection/when_disposing/cleans_up_resources.ts +30 -21
- package/queries/for_ServerSentEventHubConnection/when_receiving_unauthorized/notifies_subscriber_and_removes_subscription.ts +56 -32
- package/queries/for_ServerSentEventHubConnection/when_reconnecting/after_error.ts +23 -6
- package/queries/for_ServerSentEventHubConnection/when_reconnecting/and_an_immediate_open_wins_the_backoff_race.ts +41 -0
- package/queries/for_ServerSentEventHubConnection/when_replacing_a_subscription/ignores_messages_from_the_retired_generation.ts +92 -0
- package/queries/for_ServerSentEventHubConnection/when_subscribing/sends_subscribe_post.ts +69 -30
- package/queries/for_ServerSentEventHubConnection/when_subscription_revisions_are_not_advertised/uses_legacy_protocol.ts +69 -0
- package/queries/for_ServerSentEventHubConnection/when_unsubscribing/the_only_query.ts +43 -24
- package/queries/for_WebSocketHubConnection/when_receiving_unauthorized/notifies_subscriber_and_removes_subscription.ts +53 -29
- package/queries/for_WebSocketHubConnection/when_reconnecting/ignores_a_pending_reconnect_and_stale_socket_callbacks.ts +131 -0
- package/queries/for_WebSocketHubConnection/when_reconnecting/replaces_a_closing_socket_safely.ts +39 -0
- package/queries/for_WebSocketHubConnection/when_reconnecting/resubscribes_all_queries.ts +72 -36
- package/queries/for_WebSocketHubConnection/when_replacing_a_subscription/ignores_stale_result_unauthorized_and_error.ts +88 -0
- package/queries/for_WebSocketHubConnection/when_subscribing/to_a_query.ts +54 -27
- package/queries/for_WebSocketHubConnection/when_subscription_revisions_are_supported/upgrades_active_subscriptions_to_strict_mode.ts +72 -0
- package/queries/for_WebSocketHubConnection/when_unsubscribing/the_only_query.ts +43 -18
- package/queries/for_WebSocketHubConnection/when_unsubscribing/with_revision_support_not_advertised.ts +44 -0
|
@@ -8,63 +8,135 @@ import { QueryTransportMethod } from '../../QueryTransportMethod';
|
|
|
8
8
|
import { ObservableQuerySubscription } from '../../ObservableQuerySubscription';
|
|
9
9
|
import { SSE_HUB_ROUTE } from '../../ServerSentEventQueryConnection';
|
|
10
10
|
import { resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
11
|
+
import { HubMessageType } from '../../WebSocketHubConnection';
|
|
11
12
|
|
|
12
13
|
import * as sinon from 'sinon';
|
|
13
14
|
|
|
14
|
-
describe(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
resetSharedMultiplexer();
|
|
25
|
-
|
|
26
|
-
Globals.queryDirectMode = false;
|
|
27
|
-
Globals.queryTransportMethod = QueryTransportMethod.ServerSentEvents;
|
|
28
|
-
|
|
29
|
-
context.query.setOrigin('https://example.com');
|
|
30
|
-
callback = sinon.stub();
|
|
31
|
-
|
|
32
|
-
// EventSource doesn't exist in Node.js — inject a fake via globalThis
|
|
33
|
-
const FakeEventSourceConstructor = function (this: EventSource, url: string) {
|
|
34
|
-
capturedUrl = url;
|
|
35
|
-
Object.assign(this, {
|
|
36
|
-
onopen: null,
|
|
37
|
-
onerror: null,
|
|
38
|
-
onmessage: null,
|
|
39
|
-
close: sinon.stub(),
|
|
40
|
-
addEventListener: sinon.stub(),
|
|
41
|
-
removeEventListener: sinon.stub(),
|
|
42
|
-
});
|
|
15
|
+
describe(
|
|
16
|
+
'when subscribing with direct mode disabled and SSE transport',
|
|
17
|
+
given(an_observable_query_for, (context) => {
|
|
18
|
+
let callback: sinon.SinonStub;
|
|
19
|
+
let subscription: ObservableQuerySubscription<string>;
|
|
20
|
+
let capturedUrl: string;
|
|
21
|
+
let fetchStub: sinon.SinonStub;
|
|
22
|
+
let eventSourceInstance: EventSource & {
|
|
23
|
+
onopen: (() => void) | null;
|
|
24
|
+
onmessage: ((event: { data: string }) => void) | null;
|
|
43
25
|
};
|
|
44
|
-
|
|
26
|
+
let originalQueryDirectMode: boolean;
|
|
27
|
+
let originalTransportMethod: QueryTransportMethod;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
originalQueryDirectMode = Globals.queryDirectMode;
|
|
31
|
+
originalTransportMethod = Globals.queryTransportMethod;
|
|
32
|
+
resetSharedMultiplexer();
|
|
33
|
+
|
|
34
|
+
Globals.queryDirectMode = false;
|
|
35
|
+
Globals.queryTransportMethod = QueryTransportMethod.ServerSentEvents;
|
|
36
|
+
|
|
37
|
+
context.query.setOrigin('https://example.com');
|
|
38
|
+
callback = sinon.stub();
|
|
39
|
+
|
|
40
|
+
// EventSource doesn't exist in Node.js — inject a fake via globalThis
|
|
41
|
+
const FakeEventSourceConstructor = function (this: EventSource, url: string) {
|
|
42
|
+
capturedUrl = url;
|
|
43
|
+
eventSourceInstance = this as EventSource & {
|
|
44
|
+
onopen: (() => void) | null;
|
|
45
|
+
onmessage: ((event: { data: string }) => void) | null;
|
|
46
|
+
};
|
|
47
|
+
Object.assign(this, {
|
|
48
|
+
onopen: null,
|
|
49
|
+
onerror: null,
|
|
50
|
+
onmessage: null,
|
|
51
|
+
close: sinon.stub(),
|
|
52
|
+
addEventListener: sinon.stub(),
|
|
53
|
+
removeEventListener: sinon.stub(),
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
(globalThis as Record<string, unknown>)['EventSource'] =
|
|
57
|
+
FakeEventSourceConstructor;
|
|
58
|
+
fetchStub = sinon.stub().resolves({ ok: true } as Response);
|
|
59
|
+
(globalThis as Record<string, unknown>)['fetch'] = fetchStub;
|
|
60
|
+
|
|
61
|
+
subscription = context.query.subscribe(callback, { id: 'test-id' });
|
|
62
|
+
eventSourceInstance.onopen?.();
|
|
63
|
+
// An older Arc server omits subscription capabilities from Connected, so this fixture
|
|
64
|
+
// intentionally exercises legacy missing-revision result frames.
|
|
65
|
+
eventSourceInstance.onmessage?.({
|
|
66
|
+
data: JSON.stringify({
|
|
67
|
+
type: HubMessageType.Connected,
|
|
68
|
+
payload: 'connection-1',
|
|
69
|
+
}),
|
|
70
|
+
});
|
|
45
71
|
|
|
46
|
-
|
|
47
|
-
|
|
72
|
+
let subscribeRequest: { queryId: string; revision?: number };
|
|
73
|
+
try {
|
|
74
|
+
subscribeRequest = JSON.parse(fetchStub.firstCall.args[1].body as string);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
throw new Error('The SSE hub subscribe request was not valid JSON', {
|
|
77
|
+
cause: error,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
eventSourceInstance.onmessage?.({
|
|
81
|
+
data: JSON.stringify({
|
|
82
|
+
type: HubMessageType.QueryResult,
|
|
83
|
+
queryId: subscribeRequest.queryId,
|
|
84
|
+
payload: {
|
|
85
|
+
data: 'ready result',
|
|
86
|
+
isSuccess: true,
|
|
87
|
+
isAuthorized: true,
|
|
88
|
+
isValid: true,
|
|
89
|
+
hasExceptions: false,
|
|
90
|
+
validationResults: [],
|
|
91
|
+
exceptionMessages: [],
|
|
92
|
+
exceptionStackTrace: '',
|
|
93
|
+
paging: { page: 0, size: 0, totalItems: 0, totalPages: 0 },
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
afterEach(() => {
|
|
100
|
+
Globals.queryDirectMode = originalQueryDirectMode;
|
|
101
|
+
Globals.queryTransportMethod = originalTransportMethod;
|
|
102
|
+
if (subscription) {
|
|
103
|
+
subscription.unsubscribe();
|
|
104
|
+
}
|
|
105
|
+
delete (globalThis as Record<string, unknown>)['EventSource'];
|
|
106
|
+
delete (globalThis as Record<string, unknown>)['fetch'];
|
|
107
|
+
resetSharedMultiplexer();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should connect to the centralized SSE hub endpoint', () => {
|
|
111
|
+
capturedUrl.should.include(SSE_HUB_ROUTE);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should not include query name in URL since subscriptions are done via POST', () => {
|
|
115
|
+
capturedUrl.should.not.include('query=');
|
|
116
|
+
});
|
|
48
117
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
118
|
+
it('should return a subscription', () => {
|
|
119
|
+
(subscription === undefined).should.equal(false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should omit revisions when the server does not advertise support', () => {
|
|
123
|
+
(getSubscribeBody().revision === undefined).should.equal(true);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
function getSubscribeBody(): { revision?: number } {
|
|
127
|
+
try {
|
|
128
|
+
return JSON.parse(fetchStub.firstCall.args[1].body as string) as {
|
|
129
|
+
revision?: number;
|
|
130
|
+
};
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw new Error('Expected a valid subscribe request body', {
|
|
133
|
+
cause: error,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
54
136
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should not include query name in URL since subscriptions are done via POST', () => {
|
|
64
|
-
capturedUrl.should.not.include('query=');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should return a subscription', () => {
|
|
68
|
-
subscription.should.not.be.undefined;
|
|
69
|
-
});
|
|
70
|
-
}));
|
|
137
|
+
|
|
138
|
+
it('should normalize omitted readiness to true', () => {
|
|
139
|
+
callback.firstCall.args[0].isReady.should.equal(true);
|
|
140
|
+
});
|
|
141
|
+
}),
|
|
142
|
+
);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import { given } from '../../../given';
|
|
6
|
+
import { Globals } from '../../../Globals';
|
|
7
|
+
import { HubMessageType } from '../../WebSocketHubConnection';
|
|
8
|
+
import type { ObservableQuerySubscription } from '../../ObservableQuerySubscription';
|
|
9
|
+
import { resetSharedMultiplexer } from '../../ObservableQueryMultiplexer';
|
|
10
|
+
import { QueryTransportMethod } from '../../QueryTransportMethod';
|
|
11
|
+
import { an_observable_query_for } from '../given/an_observable_query_for';
|
|
12
|
+
|
|
13
|
+
describe(
|
|
14
|
+
'when subscribing with web socket hub payload without readiness',
|
|
15
|
+
given(an_observable_query_for, (context) => {
|
|
16
|
+
let callback: sinon.SinonStub;
|
|
17
|
+
let subscription: ObservableQuerySubscription<string>;
|
|
18
|
+
let originalQueryDirectMode: boolean;
|
|
19
|
+
let originalTransportMethod: QueryTransportMethod;
|
|
20
|
+
let originalWebSocket: typeof WebSocket;
|
|
21
|
+
let socket: {
|
|
22
|
+
readyState: number;
|
|
23
|
+
onopen: (() => void) | null;
|
|
24
|
+
onclose: (() => void) | null;
|
|
25
|
+
onerror: ((event: Event) => void) | null;
|
|
26
|
+
onmessage: ((event: { data: string }) => void) | null;
|
|
27
|
+
send: sinon.SinonStub;
|
|
28
|
+
close: sinon.SinonStub;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
originalQueryDirectMode = Globals.queryDirectMode;
|
|
33
|
+
originalTransportMethod = Globals.queryTransportMethod;
|
|
34
|
+
originalWebSocket = globalThis.WebSocket;
|
|
35
|
+
resetSharedMultiplexer();
|
|
36
|
+
|
|
37
|
+
Globals.queryDirectMode = false;
|
|
38
|
+
Globals.queryTransportMethod = QueryTransportMethod.WebSocket;
|
|
39
|
+
context.query.setOrigin('https://example.com');
|
|
40
|
+
callback = sinon.stub();
|
|
41
|
+
|
|
42
|
+
socket = {
|
|
43
|
+
readyState: 0,
|
|
44
|
+
onopen: null,
|
|
45
|
+
onclose: null,
|
|
46
|
+
onerror: null,
|
|
47
|
+
onmessage: null,
|
|
48
|
+
send: sinon.stub(),
|
|
49
|
+
close: sinon.stub(),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const WebSocketStub = sinon.stub().returns(socket);
|
|
53
|
+
Object.assign(WebSocketStub, {
|
|
54
|
+
CONNECTING: 0,
|
|
55
|
+
OPEN: 1,
|
|
56
|
+
CLOSING: 2,
|
|
57
|
+
CLOSED: 3,
|
|
58
|
+
});
|
|
59
|
+
(globalThis as Record<string, unknown>)['WebSocket'] = WebSocketStub;
|
|
60
|
+
|
|
61
|
+
subscription = context.query.subscribe(callback, { id: 'test-id' });
|
|
62
|
+
socket.readyState = 1;
|
|
63
|
+
socket.onopen?.();
|
|
64
|
+
|
|
65
|
+
// An older Arc server sends no Connected capability message, so this fixture intentionally
|
|
66
|
+
// remains in legacy mode and accepts only result frames without a revision.
|
|
67
|
+
let subscribeMessage: { queryId: string };
|
|
68
|
+
try {
|
|
69
|
+
subscribeMessage = JSON.parse(socket.send.firstCall.args[0]);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new Error('The WebSocket subscribe message was not valid JSON', {
|
|
72
|
+
cause: error,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
socket.onmessage?.({
|
|
76
|
+
data: JSON.stringify({
|
|
77
|
+
type: HubMessageType.QueryResult,
|
|
78
|
+
queryId: subscribeMessage.queryId,
|
|
79
|
+
payload: {
|
|
80
|
+
data: 'ready result',
|
|
81
|
+
isSuccess: true,
|
|
82
|
+
isAuthorized: true,
|
|
83
|
+
isValid: true,
|
|
84
|
+
hasExceptions: false,
|
|
85
|
+
validationResults: [],
|
|
86
|
+
exceptionMessages: [],
|
|
87
|
+
exceptionStackTrace: '',
|
|
88
|
+
paging: { page: 0, size: 0, totalItems: 0, totalPages: 0 },
|
|
89
|
+
},
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
afterEach(() => {
|
|
95
|
+
subscription?.unsubscribe();
|
|
96
|
+
Globals.queryDirectMode = originalQueryDirectMode;
|
|
97
|
+
Globals.queryTransportMethod = originalTransportMethod;
|
|
98
|
+
globalThis.WebSocket = originalWebSocket;
|
|
99
|
+
resetSharedMultiplexer();
|
|
100
|
+
sinon.restore();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should normalize omitted readiness to true', () => {
|
|
104
|
+
callback.firstCall.args[0].isReady.should.equal(true);
|
|
105
|
+
});
|
|
106
|
+
}),
|
|
107
|
+
);
|
package/queries/for_QueryInstanceCache/when_setting_last_result/with_only_readiness_changed.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import { PagingInfo } from '../../PagingInfo';
|
|
6
|
+
import { QueryInstanceCache } from '../../QueryInstanceCache';
|
|
7
|
+
import { QueryResultWithState } from '../../QueryResultWithState';
|
|
8
|
+
|
|
9
|
+
describe('when setting the last result with only readiness changed', () => {
|
|
10
|
+
const key = 'MyQuery::';
|
|
11
|
+
const data = ['a', 'b'];
|
|
12
|
+
let listener: sinon.SinonStub;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
const cache = new QueryInstanceCache();
|
|
16
|
+
cache.getOrCreate(key, () => ({}));
|
|
17
|
+
listener = sinon.stub();
|
|
18
|
+
cache.addListener<string[]>(key, listener);
|
|
19
|
+
|
|
20
|
+
cache.setLastResult(
|
|
21
|
+
key,
|
|
22
|
+
new QueryResultWithState(
|
|
23
|
+
data,
|
|
24
|
+
PagingInfo.noPaging,
|
|
25
|
+
false,
|
|
26
|
+
true,
|
|
27
|
+
true,
|
|
28
|
+
[],
|
|
29
|
+
false,
|
|
30
|
+
[],
|
|
31
|
+
'',
|
|
32
|
+
false,
|
|
33
|
+
undefined,
|
|
34
|
+
false,
|
|
35
|
+
),
|
|
36
|
+
);
|
|
37
|
+
listener.resetHistory();
|
|
38
|
+
|
|
39
|
+
cache.setLastResult(
|
|
40
|
+
key,
|
|
41
|
+
new QueryResultWithState(
|
|
42
|
+
data,
|
|
43
|
+
PagingInfo.noPaging,
|
|
44
|
+
false,
|
|
45
|
+
true,
|
|
46
|
+
true,
|
|
47
|
+
[],
|
|
48
|
+
false,
|
|
49
|
+
[],
|
|
50
|
+
'',
|
|
51
|
+
false,
|
|
52
|
+
undefined,
|
|
53
|
+
true,
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
afterEach(() => sinon.restore());
|
|
59
|
+
|
|
60
|
+
it('should notify the listener', () => listener.calledOnce.should.be.true);
|
|
61
|
+
it('should provide the changed readiness', () =>
|
|
62
|
+
listener.firstCall.args[0].isReady.should.be.true);
|
|
63
|
+
});
|
package/queries/for_QueryResult/when_constructing_from_a_server_result/with_readiness_false.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { QueryResult } from '../../QueryResult';
|
|
5
|
+
|
|
6
|
+
describe('when constructing from a server result with readiness false', () => {
|
|
7
|
+
const result = new QueryResult(
|
|
8
|
+
{
|
|
9
|
+
data: null,
|
|
10
|
+
isSuccess: false,
|
|
11
|
+
isReady: false,
|
|
12
|
+
isAuthorized: true,
|
|
13
|
+
isValid: true,
|
|
14
|
+
hasExceptions: false,
|
|
15
|
+
validationResults: [],
|
|
16
|
+
exceptionMessages: [],
|
|
17
|
+
exceptionStackTrace: '',
|
|
18
|
+
paging: { page: 0, size: 0, totalItems: 0, totalPages: 0 },
|
|
19
|
+
},
|
|
20
|
+
Object,
|
|
21
|
+
false,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
it('should not be ready', () => result.isReady.should.be.false);
|
|
25
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { QueryResult } from '../../QueryResult';
|
|
5
|
+
|
|
6
|
+
describe('when constructing from a server result without readiness', () => {
|
|
7
|
+
const result = new QueryResult(
|
|
8
|
+
{
|
|
9
|
+
data: {},
|
|
10
|
+
isSuccess: true,
|
|
11
|
+
isAuthorized: true,
|
|
12
|
+
isValid: true,
|
|
13
|
+
hasExceptions: false,
|
|
14
|
+
validationResults: [],
|
|
15
|
+
exceptionMessages: [],
|
|
16
|
+
exceptionStackTrace: '',
|
|
17
|
+
paging: { page: 0, size: 0, totalItems: 0, totalPages: 0 },
|
|
18
|
+
},
|
|
19
|
+
Object,
|
|
20
|
+
false,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
it('should be ready', () => result.isReady.should.be.true);
|
|
24
|
+
});
|
package/queries/for_QueryResultWithState/when_creating_from_query_result/with_readiness_false.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { QueryResult } from '../../QueryResult';
|
|
5
|
+
import { QueryResultWithState } from '../../QueryResultWithState';
|
|
6
|
+
|
|
7
|
+
describe('when creating from query result with readiness false', () => {
|
|
8
|
+
const queryResult = new QueryResult(
|
|
9
|
+
{
|
|
10
|
+
data: null,
|
|
11
|
+
isSuccess: false,
|
|
12
|
+
isReady: false,
|
|
13
|
+
isAuthorized: true,
|
|
14
|
+
isValid: true,
|
|
15
|
+
hasExceptions: false,
|
|
16
|
+
validationResults: [],
|
|
17
|
+
exceptionMessages: [],
|
|
18
|
+
exceptionStackTrace: '',
|
|
19
|
+
paging: { page: 0, size: 0, totalItems: 0, totalPages: 0 },
|
|
20
|
+
},
|
|
21
|
+
Object,
|
|
22
|
+
false,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const result = QueryResultWithState.fromQueryResult(queryResult, false);
|
|
26
|
+
|
|
27
|
+
it('should not be ready', () => result.isReady.should.be.false);
|
|
28
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import type { IQueryResult } from '../../IQueryResult';
|
|
5
|
+
import { PagingInfo } from '../../PagingInfo';
|
|
6
|
+
import { QueryResultWithState } from '../../QueryResultWithState';
|
|
7
|
+
|
|
8
|
+
describe('when creating from query result without readiness', () => {
|
|
9
|
+
const queryResult: IQueryResult<string> = {
|
|
10
|
+
data: 'ready result',
|
|
11
|
+
paging: PagingInfo.noPaging,
|
|
12
|
+
isSuccess: true,
|
|
13
|
+
isAuthorized: true,
|
|
14
|
+
isValid: true,
|
|
15
|
+
validationResults: [],
|
|
16
|
+
hasExceptions: false,
|
|
17
|
+
exceptionMessages: [],
|
|
18
|
+
exceptionStackTrace: '',
|
|
19
|
+
hasData: true,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const result = QueryResultWithState.fromQueryResult(queryResult, false);
|
|
23
|
+
|
|
24
|
+
it('should be ready', () => result.isReady.should.be.true);
|
|
25
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
export class a_deferred_promise<T> {
|
|
5
|
+
readonly promise: Promise<T>;
|
|
6
|
+
resolve!: (value: T) => void;
|
|
7
|
+
reject!: (reason?: unknown) => void;
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
this.promise = new Promise<T>((resolve, reject) => {
|
|
11
|
+
this.resolve = resolve;
|
|
12
|
+
this.reject = reject;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
package/queries/for_ServerSentEventHubConnection/given/a_server_sent_event_hub_connection.ts
CHANGED
|
@@ -16,6 +16,7 @@ export class a_server_sent_event_hub_connection {
|
|
|
16
16
|
close: sinon.SinonStub;
|
|
17
17
|
readyState: number;
|
|
18
18
|
};
|
|
19
|
+
eventSources!: Array<typeof this.fakeEventSource>;
|
|
19
20
|
policy!: sinon.SinonStubbedInstance<IReconnectPolicy>;
|
|
20
21
|
fetchStub!: sinon.SinonStub;
|
|
21
22
|
|
|
@@ -29,20 +30,28 @@ export class a_server_sent_event_hub_connection {
|
|
|
29
30
|
* accumulation across tests sharing the same context instance.
|
|
30
31
|
*/
|
|
31
32
|
setup(): void {
|
|
33
|
+
this.eventSources = [];
|
|
32
34
|
this.fakeEventSource = {
|
|
33
35
|
onopen: null,
|
|
34
36
|
onmessage: null,
|
|
35
37
|
onerror: null,
|
|
36
38
|
close: sinon.stub(),
|
|
37
|
-
readyState: 0,
|
|
39
|
+
readyState: 0,
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
41
43
|
const self = this;
|
|
42
44
|
const FakeEventSourceClass = function (this: any) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
const eventSource = {
|
|
46
|
+
onopen: null,
|
|
47
|
+
onmessage: null,
|
|
48
|
+
onerror: null,
|
|
49
|
+
close: sinon.stub(),
|
|
50
|
+
readyState: 0, // CONNECTING
|
|
51
|
+
};
|
|
52
|
+
self.eventSources.push(eventSource);
|
|
53
|
+
self.fakeEventSource = eventSource;
|
|
54
|
+
return eventSource;
|
|
46
55
|
};
|
|
47
56
|
(globalThis as any)['EventSource'] = FakeEventSourceClass;
|
|
48
57
|
(globalThis as any)['EventSource'].CONNECTING = 0;
|
|
@@ -66,7 +75,7 @@ export class a_server_sent_event_hub_connection {
|
|
|
66
75
|
'',
|
|
67
76
|
undefined,
|
|
68
77
|
undefined,
|
|
69
|
-
this.policy
|
|
78
|
+
this.policy,
|
|
70
79
|
);
|
|
71
80
|
}
|
|
72
81
|
|
|
@@ -75,8 +84,10 @@ export class a_server_sent_event_hub_connection {
|
|
|
75
84
|
this.fakeEventSource.onopen?.();
|
|
76
85
|
}
|
|
77
86
|
|
|
78
|
-
simulateMessage(payload:
|
|
79
|
-
this.fakeEventSource.onmessage?.({
|
|
87
|
+
simulateMessage(payload: Record<string, unknown>): void {
|
|
88
|
+
this.fakeEventSource.onmessage?.({
|
|
89
|
+
data: JSON.stringify(payload),
|
|
90
|
+
} as MessageEvent);
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
simulateError(): void {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import { a_server_sent_event_hub_connection } from '../given/a_server_sent_event_hub_connection';
|
|
6
|
+
import { given } from '../../../given';
|
|
7
|
+
import { HubMessageType } from '../../WebSocketHubConnection';
|
|
8
|
+
|
|
9
|
+
describe(
|
|
10
|
+
'when a retired EventSource fires connected and error callbacks',
|
|
11
|
+
given(a_server_sent_event_hub_connection, (context) => {
|
|
12
|
+
let staleMessage: (event: MessageEvent) => void;
|
|
13
|
+
let staleError: () => void;
|
|
14
|
+
let currentSource: typeof context.fakeEventSource;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
context.setup();
|
|
18
|
+
sinon.stub(console, 'warn');
|
|
19
|
+
context.connection.subscribe('q1', { queryName: 'MyQuery' }, sinon.stub());
|
|
20
|
+
context.simulateOpen();
|
|
21
|
+
context.simulateMessage({
|
|
22
|
+
type: HubMessageType.Connected,
|
|
23
|
+
payload: 'connection-a',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const retiredSource = context.eventSources[0];
|
|
27
|
+
staleMessage = retiredSource.onmessage!;
|
|
28
|
+
staleError = retiredSource.onerror!;
|
|
29
|
+
staleError();
|
|
30
|
+
|
|
31
|
+
const reconnect = (context.policy.schedule as sinon.SinonStub).firstCall
|
|
32
|
+
.args[0] as () => void;
|
|
33
|
+
reconnect();
|
|
34
|
+
currentSource = context.eventSources[1];
|
|
35
|
+
context.simulateOpen();
|
|
36
|
+
context.simulateMessage({
|
|
37
|
+
type: HubMessageType.Connected,
|
|
38
|
+
payload: 'connection-b',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
staleMessage({
|
|
42
|
+
data: JSON.stringify({
|
|
43
|
+
type: HubMessageType.Connected,
|
|
44
|
+
payload: 'stale-connection',
|
|
45
|
+
}),
|
|
46
|
+
} as MessageEvent);
|
|
47
|
+
staleError();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
afterEach(() => sinon.restore());
|
|
51
|
+
|
|
52
|
+
it('should not send another subscription for stale connected', () =>
|
|
53
|
+
context.fetchStub.callCount.should.equal(2));
|
|
54
|
+
it('should keep the current EventSource open', () =>
|
|
55
|
+
currentSource.close.called.should.be.false);
|
|
56
|
+
it('should not schedule another reconnect for stale error', () =>
|
|
57
|
+
(context.policy.schedule as sinon.SinonStub).calledOnce.should.be.true);
|
|
58
|
+
}),
|
|
59
|
+
);
|