@cratis/arc 20.63.0 → 20.64.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/EventSourceFactory.ts +12 -0
- package/Globals.ts +8 -0
- package/dist/cjs/Globals.js.map +1 -1
- package/dist/cjs/queries/ServerSentEventHubConnection.js +1 -1
- package/dist/cjs/queries/ServerSentEventHubConnection.js.map +1 -1
- package/dist/cjs/queries/ServerSentEventQueryConnection.js +6 -3
- package/dist/cjs/queries/ServerSentEventQueryConnection.js.map +1 -1
- package/dist/esm/EventSourceFactory.d.ts +2 -0
- package/dist/esm/EventSourceFactory.d.ts.map +1 -0
- package/dist/esm/EventSourceFactory.js +2 -0
- package/dist/esm/EventSourceFactory.js.map +1 -0
- package/dist/esm/Globals.d.ts +2 -0
- package/dist/esm/Globals.d.ts.map +1 -1
- package/dist/esm/Globals.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/queries/ServerSentEventHubConnection.js +1 -1
- package/dist/esm/queries/ServerSentEventHubConnection.js.map +1 -1
- package/dist/esm/queries/ServerSentEventQueryConnection.d.ts.map +1 -1
- package/dist/esm/queries/ServerSentEventQueryConnection.js +6 -3
- package/dist/esm/queries/ServerSentEventQueryConnection.js.map +1 -1
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscribing/uses_custom_event_source_factory.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscribing/uses_custom_event_source_factory.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscribing/uses_custom_event_source_factory.js +38 -0
- package/dist/esm/queries/for_ServerSentEventHubConnection/when_subscribing/uses_custom_event_source_factory.js.map +1 -0
- package/dist/esm/queries/for_ServerSentEventQueryConnection/when_connecting/with_custom_event_source_factory.d.ts +2 -0
- package/dist/esm/queries/for_ServerSentEventQueryConnection/when_connecting/with_custom_event_source_factory.d.ts.map +1 -0
- package/dist/esm/queries/for_ServerSentEventQueryConnection/when_connecting/with_custom_event_source_factory.js +43 -0
- package/dist/esm/queries/for_ServerSentEventQueryConnection/when_connecting/with_custom_event_source_factory.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/index.ts +1 -0
- package/package.json +1 -1
- package/queries/ServerSentEventHubConnection.ts +1 -1
- package/queries/ServerSentEventQueryConnection.ts +5 -3
- package/queries/for_ServerSentEventHubConnection/when_subscribing/uses_custom_event_source_factory.ts +57 -0
- package/queries/for_ServerSentEventQueryConnection/when_connecting/with_custom_event_source_factory.ts +63 -0
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -192,7 +192,7 @@ export class ServerSentEventHubConnection implements IObservableQueryHubConnecti
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
this._connectionId = undefined;
|
|
195
|
-
this._eventSource = new EventSource(url);
|
|
195
|
+
this._eventSource = Globals.eventSourceFactory ? Globals.eventSourceFactory(url) : new EventSource(url);
|
|
196
196
|
|
|
197
197
|
this._eventSource.onopen = () => {
|
|
198
198
|
if (this._disconnected) return;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Cratis. All rights reserved.
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
|
+
import { Globals } from '../Globals';
|
|
4
5
|
import { IObservableQueryConnection } from './IObservableQueryConnection';
|
|
5
6
|
import { DataReceived } from './ObservableQueryConnection';
|
|
6
7
|
import { QueryResult } from './QueryResult';
|
|
@@ -39,8 +40,9 @@ export class ServerSentEventQueryConnection<TDataType> implements IObservableQue
|
|
|
39
40
|
connect(dataReceived: DataReceived<TDataType>, queryArguments?: object): void {
|
|
40
41
|
if (this._disconnected) return;
|
|
41
42
|
|
|
42
|
-
// Guard against environments where EventSource is not available (e.g. Node.js, SSR)
|
|
43
|
-
|
|
43
|
+
// Guard against environments where EventSource is not available (e.g. Node.js, SSR)
|
|
44
|
+
// and no custom factory has been supplied to substitute it.
|
|
45
|
+
if (!Globals.eventSourceFactory && typeof EventSource === 'undefined') {
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
48
|
|
|
@@ -56,7 +58,7 @@ export class ServerSentEventQueryConnection<TDataType> implements IObservableQue
|
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
this._eventSource = new EventSource(url);
|
|
61
|
+
this._eventSource = Globals.eventSourceFactory ? Globals.eventSourceFactory(url) : new EventSource(url);
|
|
60
62
|
|
|
61
63
|
this._eventSource.onmessage = (event: MessageEvent) => {
|
|
62
64
|
if (this._disconnected) return;
|
|
@@ -0,0 +1,57 @@
|
|
|
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 { Globals } from '../../../Globals';
|
|
6
|
+
import { EventSourceFactory } from '../../../EventSourceFactory';
|
|
7
|
+
import { a_server_sent_event_hub_connection } from '../given/a_server_sent_event_hub_connection';
|
|
8
|
+
import { given } from '../../../given';
|
|
9
|
+
import { HubMessageType } from '../../WebSocketHubConnection';
|
|
10
|
+
|
|
11
|
+
interface FakeEventSource {
|
|
12
|
+
onopen: (() => void) | null;
|
|
13
|
+
onmessage: ((event: MessageEvent) => void) | null;
|
|
14
|
+
onerror: (() => void) | null;
|
|
15
|
+
close: sinon.SinonStub;
|
|
16
|
+
readyState: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('when subscribing with a custom event source factory configured', given(a_server_sent_event_hub_connection, context => {
|
|
20
|
+
let customEventSource: FakeEventSource;
|
|
21
|
+
let factoryStub: sinon.SinonStub;
|
|
22
|
+
let originalFactory: EventSourceFactory | undefined;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
originalFactory = Globals.eventSourceFactory;
|
|
26
|
+
|
|
27
|
+
customEventSource = {
|
|
28
|
+
onopen: null,
|
|
29
|
+
onmessage: null,
|
|
30
|
+
onerror: null,
|
|
31
|
+
close: sinon.stub(),
|
|
32
|
+
readyState: 1, // OPEN
|
|
33
|
+
};
|
|
34
|
+
factoryStub = sinon.stub().returns(customEventSource);
|
|
35
|
+
Globals.eventSourceFactory = factoryStub as unknown as EventSourceFactory;
|
|
36
|
+
|
|
37
|
+
context.setup();
|
|
38
|
+
context.connection.subscribe('q1', { queryName: 'MyQuery' }, sinon.stub());
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
Globals.eventSourceFactory = originalFactory;
|
|
43
|
+
sinon.restore();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should call the custom factory with the SSE hub url', () => factoryStub.calledOnce.should.be.true);
|
|
47
|
+
it('should pass the hub url to the factory', () => factoryStub.getCall(0).args[0].should.equal('http://localhost/.cratis/queries/sse'));
|
|
48
|
+
it('should not use the default global EventSource', () => (context.fakeEventSource.onopen === null).should.be.true);
|
|
49
|
+
|
|
50
|
+
describe('when the custom event source receives the Connected message', () => {
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
customEventSource.onmessage!({ data: JSON.stringify({ type: HubMessageType.Connected, payload: 'conn-1' }) } as MessageEvent);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should record the connection as open', () => context.connection.isConnected.should.be.true);
|
|
56
|
+
});
|
|
57
|
+
}));
|
|
@@ -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 { Globals } from '../../../Globals';
|
|
6
|
+
import { EventSourceFactory } from '../../../EventSourceFactory';
|
|
7
|
+
import { ServerSentEventQueryConnection } from '../../ServerSentEventQueryConnection';
|
|
8
|
+
import { QueryResult } from '../../QueryResult';
|
|
9
|
+
|
|
10
|
+
interface FakeEventSource {
|
|
11
|
+
onmessage: ((event: MessageEvent) => void) | null;
|
|
12
|
+
onerror: (() => void) | null;
|
|
13
|
+
close: sinon.SinonStub;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('when connecting with a custom event source factory configured and no global EventSource available', () => {
|
|
17
|
+
let originalEventSource: typeof EventSource;
|
|
18
|
+
let originalFactory: EventSourceFactory | undefined;
|
|
19
|
+
let fakeEventSource: FakeEventSource;
|
|
20
|
+
let factoryStub: sinon.SinonStub;
|
|
21
|
+
let connection: ServerSentEventQueryConnection<string[]>;
|
|
22
|
+
let receivedData: QueryResult<string[]>[];
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
originalEventSource = (globalThis as Record<string, unknown>)['EventSource'] as typeof EventSource;
|
|
26
|
+
delete (globalThis as Record<string, unknown>)['EventSource'];
|
|
27
|
+
|
|
28
|
+
originalFactory = Globals.eventSourceFactory;
|
|
29
|
+
|
|
30
|
+
fakeEventSource = {
|
|
31
|
+
onmessage: null,
|
|
32
|
+
onerror: null,
|
|
33
|
+
close: sinon.stub(),
|
|
34
|
+
};
|
|
35
|
+
factoryStub = sinon.stub().returns(fakeEventSource);
|
|
36
|
+
Globals.eventSourceFactory = factoryStub as unknown as EventSourceFactory;
|
|
37
|
+
|
|
38
|
+
receivedData = [];
|
|
39
|
+
connection = new ServerSentEventQueryConnection<string[]>(new URL('http://localhost/.cratis/queries/sse?query=Test'));
|
|
40
|
+
connection.connect((result: QueryResult<string[]>) => receivedData.push(result));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
if (originalEventSource !== undefined) {
|
|
45
|
+
(globalThis as Record<string, unknown>)['EventSource'] = originalEventSource;
|
|
46
|
+
}
|
|
47
|
+
Globals.eventSourceFactory = originalFactory;
|
|
48
|
+
sinon.restore();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should call the custom factory instead of the global EventSource constructor', () => factoryStub.calledOnce.should.be.true);
|
|
52
|
+
it('should pass the connection url to the factory', () => (factoryStub.getCall(0).args[0] as string).should.contain('/.cratis/queries/sse'));
|
|
53
|
+
|
|
54
|
+
describe('when a message arrives on the custom event source', () => {
|
|
55
|
+
const result = { data: ['a', 'b'], isSuccess: true, isAuthorized: true, isValid: true, hasExceptions: false, hasData: true, validationResults: [], exceptionMessages: [], exceptionStackTrace: '', paging: { page: 0, size: 0, totalItems: 0, totalPages: 0 } };
|
|
56
|
+
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
fakeEventSource.onmessage!({ data: JSON.stringify(result) } as MessageEvent);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should deliver the payload to the callback', () => receivedData.length.should.equal(1));
|
|
62
|
+
});
|
|
63
|
+
});
|