@powersync/service-rsocket-router 0.0.6 → 0.0.8
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/README.md +1 -1
- package/dist/router/ReactiveSocketRouter.d.ts +6 -0
- package/dist/router/ReactiveSocketRouter.js +25 -14
- package/dist/router/ReactiveSocketRouter.js.map +1 -1
- package/dist/router/transport/WebSocketServerTransport.d.ts +19 -0
- package/dist/router/transport/WebSocketServerTransport.js +86 -0
- package/dist/router/transport/WebSocketServerTransport.js.map +1 -0
- package/dist/router/transport/WebsocketDuplexConnection.d.ts +17 -0
- package/dist/router/transport/WebsocketDuplexConnection.js +105 -0
- package/dist/router/transport/WebsocketDuplexConnection.js.map +1 -0
- package/dist/router/types.d.ts +6 -4
- package/dist/router/types.js.map +1 -1
- package/dist/utils/BaseObserver.js.map +1 -1
- package/package.json +5 -8
package/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/**
|
|
3
|
+
* This is a small Router wrapper which uses the RSocket lib
|
|
4
|
+
* to expose reactive websocket stream in an interface similar to
|
|
5
|
+
* other Journey micro routers.
|
|
6
|
+
*/
|
|
2
7
|
import * as http from 'http';
|
|
3
8
|
import { Payload } from 'rsocket-core';
|
|
4
9
|
import { SocketRouterObserver } from './SocketRouterListener.js';
|
|
5
10
|
import { CommonParams, IReactiveStream, IReactiveStreamInput, ReactiveSocketRouterOptions, SocketResponder } from './types.js';
|
|
6
11
|
export declare class ReactiveSocketRouter<C> {
|
|
7
12
|
protected options?: ReactiveSocketRouterOptions<C> | undefined;
|
|
13
|
+
protected activeConnections: number;
|
|
8
14
|
constructor(options?: ReactiveSocketRouterOptions<C> | undefined);
|
|
9
15
|
reactiveStream<I, O>(path: string, stream: IReactiveStreamInput<I, O, C>): IReactiveStream<I, O, C>;
|
|
10
16
|
/**
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is a small Router wrapper which uses the RSocket lib
|
|
3
|
-
* to expose reactive websocket stream in an interface similar to
|
|
4
|
-
* other journey micro routers.
|
|
5
|
-
*/
|
|
6
|
-
import * as micro from '@journeyapps-platform/micro';
|
|
7
1
|
import { RSocketServer } from 'rsocket-core';
|
|
8
|
-
import { WebsocketServerTransport } from 'rsocket-websocket-server';
|
|
9
2
|
import * as ws from 'ws';
|
|
10
3
|
import { SocketRouterObserver } from './SocketRouterListener.js';
|
|
11
4
|
import { RS_ENDPOINT_TYPE } from './types.js';
|
|
5
|
+
import { WebsocketServerTransport } from './transport/WebSocketServerTransport.js';
|
|
6
|
+
import { errors, logger } from '@powersync/lib-services-framework';
|
|
12
7
|
export class ReactiveSocketRouter {
|
|
13
8
|
constructor(options) {
|
|
14
9
|
this.options = options;
|
|
10
|
+
this.activeConnections = 0;
|
|
15
11
|
}
|
|
16
12
|
reactiveStream(path, stream) {
|
|
17
13
|
return {
|
|
@@ -44,10 +40,17 @@ export class ReactiveSocketRouter {
|
|
|
44
40
|
transport,
|
|
45
41
|
acceptor: {
|
|
46
42
|
accept: async (payload) => {
|
|
43
|
+
const { max_concurrent_connections } = this.options ?? {};
|
|
44
|
+
if (max_concurrent_connections && this.activeConnections >= max_concurrent_connections) {
|
|
45
|
+
throw new errors.JourneyError({
|
|
46
|
+
code: '429',
|
|
47
|
+
description: `Maximum active concurrent connections limit has been reached`
|
|
48
|
+
});
|
|
49
|
+
}
|
|
47
50
|
// Throwing an exception in this context will be returned to the client side request
|
|
48
51
|
if (!payload.metadata) {
|
|
49
52
|
// Meta data is required for endpoint handler path matching
|
|
50
|
-
throw new
|
|
53
|
+
throw new errors.AuthorizationError('No context meta data provided');
|
|
51
54
|
}
|
|
52
55
|
const context = await params.contextProvider(payload.metadata);
|
|
53
56
|
return {
|
|
@@ -55,12 +58,14 @@ export class ReactiveSocketRouter {
|
|
|
55
58
|
requestStream: (payload, initialN, responder) => {
|
|
56
59
|
const observer = new SocketRouterObserver();
|
|
57
60
|
handleReactiveStream(context, { payload, initialN, responder }, observer, params).catch((ex) => {
|
|
58
|
-
|
|
61
|
+
logger.error(ex);
|
|
59
62
|
responder.onError(ex);
|
|
60
63
|
responder.onComplete();
|
|
61
64
|
});
|
|
65
|
+
this.activeConnections++;
|
|
62
66
|
return {
|
|
63
67
|
cancel: () => {
|
|
68
|
+
this.activeConnections--;
|
|
64
69
|
observer.triggerCancel();
|
|
65
70
|
},
|
|
66
71
|
onExtension: () => observer.triggerExtension(),
|
|
@@ -81,31 +86,32 @@ export class ReactiveSocketRouter {
|
|
|
81
86
|
export async function handleReactiveStream(context, request, observer, params) {
|
|
82
87
|
const { payload, responder, initialN } = request;
|
|
83
88
|
const { metadata } = payload;
|
|
89
|
+
const startTime = new Date();
|
|
84
90
|
const exitWithError = (error) => {
|
|
85
91
|
responder.onError(error);
|
|
86
92
|
responder.onComplete();
|
|
87
93
|
};
|
|
88
94
|
if (!metadata) {
|
|
89
|
-
return exitWithError(new
|
|
95
|
+
return exitWithError(new errors.ValidationError('Metadata is not provided'));
|
|
90
96
|
}
|
|
91
97
|
const meta = await params.metaDecoder(metadata);
|
|
92
98
|
const { path } = meta;
|
|
93
99
|
const route = params.endpoints.find((e) => e.path == path && e.type == RS_ENDPOINT_TYPE.STREAM);
|
|
94
100
|
if (!route) {
|
|
95
|
-
return exitWithError(new
|
|
101
|
+
return exitWithError(new errors.ResourceNotFound('route', `No route for ${path} is configured`));
|
|
96
102
|
}
|
|
97
103
|
const { handler, authorize, validator, decoder = params.payloadDecoder } = route;
|
|
98
104
|
const requestPayload = await decoder(payload.data || undefined);
|
|
99
105
|
if (validator) {
|
|
100
106
|
const isValid = validator.validate(requestPayload);
|
|
101
107
|
if (!isValid.valid) {
|
|
102
|
-
return exitWithError(new
|
|
108
|
+
return exitWithError(new errors.ValidationError(isValid.errors));
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
if (authorize) {
|
|
106
112
|
const isAuthorized = await authorize({ params: requestPayload, context, observer, responder });
|
|
107
113
|
if (!isAuthorized.authorized) {
|
|
108
|
-
return exitWithError(new
|
|
114
|
+
return exitWithError(new errors.AuthorizationError(isAuthorized.errors));
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
117
|
try {
|
|
@@ -118,9 +124,14 @@ export async function handleReactiveStream(context, request, observer, params) {
|
|
|
118
124
|
});
|
|
119
125
|
}
|
|
120
126
|
catch (ex) {
|
|
121
|
-
|
|
127
|
+
logger.error(ex);
|
|
122
128
|
responder.onError(ex);
|
|
123
129
|
responder.onComplete();
|
|
124
130
|
}
|
|
131
|
+
finally {
|
|
132
|
+
logger.info(`STREAM ${path}`, {
|
|
133
|
+
duration_ms: Math.round(new Date().valueOf() - startTime.valueOf() + Number.EPSILON)
|
|
134
|
+
});
|
|
135
|
+
}
|
|
125
136
|
}
|
|
126
137
|
//# sourceMappingURL=ReactiveSocketRouter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactiveSocketRouter.js","sourceRoot":"","sources":["../../src/router/ReactiveSocketRouter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReactiveSocketRouter.js","sourceRoot":"","sources":["../../src/router/ReactiveSocketRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Closeable, Demultiplexer, DuplexConnection, Frame, FrameHandler, Multiplexer, Outbound, ServerTransport } from 'rsocket-core';
|
|
2
|
+
import * as WebSocket from 'ws';
|
|
3
|
+
export type SocketFactory = (options: SocketOptions) => WebSocket.WebSocketServer;
|
|
4
|
+
export type SocketOptions = {
|
|
5
|
+
host?: string;
|
|
6
|
+
port?: number;
|
|
7
|
+
};
|
|
8
|
+
export type ServerOptions = SocketOptions & {
|
|
9
|
+
wsCreator?: SocketFactory;
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare class WebsocketServerTransport implements ServerTransport {
|
|
13
|
+
private readonly host;
|
|
14
|
+
private readonly port;
|
|
15
|
+
private readonly factory;
|
|
16
|
+
constructor(options: ServerOptions);
|
|
17
|
+
bind(connectionAcceptor: (frame: Frame, connection: DuplexConnection) => Promise<void>, multiplexerDemultiplexerFactory: (frame: Frame, outbound: Outbound & Closeable) => Multiplexer & Demultiplexer & FrameHandler): Promise<Closeable>;
|
|
18
|
+
private connectServer;
|
|
19
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Adapted from https://github.com/rsocket/rsocket-js/blob/1.0.x-alpha/packages/rsocket-websocket-client/src/WebsocketClientTransport.ts
|
|
3
|
+
* Copyright 2021-2022 the original author or authors.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { Deferred } from 'rsocket-core';
|
|
18
|
+
import * as WebSocket from 'ws';
|
|
19
|
+
import { WebsocketDuplexConnection } from './WebsocketDuplexConnection.js';
|
|
20
|
+
import { logger } from '@powersync/lib-services-framework';
|
|
21
|
+
const defaultFactory = (options) => {
|
|
22
|
+
return new WebSocket.WebSocketServer({
|
|
23
|
+
host: options.host,
|
|
24
|
+
port: options.port
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
export class WebsocketServerTransport {
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.host = options.host;
|
|
30
|
+
this.port = options.port;
|
|
31
|
+
this.factory = options.wsCreator ?? defaultFactory;
|
|
32
|
+
}
|
|
33
|
+
async bind(connectionAcceptor, multiplexerDemultiplexerFactory) {
|
|
34
|
+
const websocketServer = await this.connectServer();
|
|
35
|
+
const serverCloseable = new ServerCloseable(websocketServer);
|
|
36
|
+
const connectionListener = (websocket) => {
|
|
37
|
+
try {
|
|
38
|
+
websocket.binaryType = 'nodebuffer';
|
|
39
|
+
const duplex = WebSocket.createWebSocketStream(websocket);
|
|
40
|
+
WebsocketDuplexConnection.create(duplex, connectionAcceptor, multiplexerDemultiplexerFactory, websocket);
|
|
41
|
+
}
|
|
42
|
+
catch (ex) {
|
|
43
|
+
logger.error(`Could not create duplex connection`, ex);
|
|
44
|
+
if (websocket.readyState == websocket.OPEN) {
|
|
45
|
+
websocket.close();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const closeListener = (error) => {
|
|
50
|
+
serverCloseable.close(error);
|
|
51
|
+
};
|
|
52
|
+
websocketServer.addListener('connection', connectionListener);
|
|
53
|
+
websocketServer.addListener('close', closeListener);
|
|
54
|
+
websocketServer.addListener('error', closeListener);
|
|
55
|
+
return serverCloseable;
|
|
56
|
+
}
|
|
57
|
+
connectServer() {
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const websocketServer = this.factory({
|
|
60
|
+
host: this.host,
|
|
61
|
+
port: this.port
|
|
62
|
+
});
|
|
63
|
+
const earlyCloseListener = (error) => {
|
|
64
|
+
reject(error);
|
|
65
|
+
};
|
|
66
|
+
websocketServer.addListener('close', earlyCloseListener);
|
|
67
|
+
websocketServer.addListener('error', earlyCloseListener);
|
|
68
|
+
websocketServer.addListener('listening', () => resolve(websocketServer));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
class ServerCloseable extends Deferred {
|
|
73
|
+
constructor(server) {
|
|
74
|
+
super();
|
|
75
|
+
this.server = server;
|
|
76
|
+
}
|
|
77
|
+
close(error) {
|
|
78
|
+
if (this.done) {
|
|
79
|
+
super.close(error);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// For this package's use case the server is externally closed
|
|
83
|
+
super.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=WebSocketServerTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketServerTransport.js","sourceRoot":"","sources":["../../../src/router/transport/WebSocketServerTransport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { Closeable, Deferred, Demultiplexer, DuplexConnection, Frame, FrameHandler, Multiplexer, Outbound } from 'rsocket-core';
|
|
3
|
+
import { Duplex } from 'stream';
|
|
4
|
+
import WebSocket from 'ws';
|
|
5
|
+
export declare class WebsocketDuplexConnection extends Deferred implements DuplexConnection, Outbound {
|
|
6
|
+
private websocketDuplex;
|
|
7
|
+
private rawSocket;
|
|
8
|
+
readonly multiplexerDemultiplexer: Multiplexer & Demultiplexer & FrameHandler;
|
|
9
|
+
constructor(websocketDuplex: Duplex, frame: Frame, multiplexerDemultiplexerFactory: (frame: Frame, outbound: Outbound & Closeable) => Multiplexer & Demultiplexer & FrameHandler, rawSocket: WebSocket.WebSocket);
|
|
10
|
+
get availability(): number;
|
|
11
|
+
close(error?: Error): void;
|
|
12
|
+
send(frame: Frame): void;
|
|
13
|
+
private handleClosed;
|
|
14
|
+
private handleError;
|
|
15
|
+
private handleMessage;
|
|
16
|
+
static create(socket: Duplex, connectionAcceptor: (frame: Frame, connection: DuplexConnection) => Promise<void>, multiplexerDemultiplexerFactory: (frame: Frame, outbound: Outbound & Closeable) => Multiplexer & Demultiplexer & FrameHandler, rawSocket: WebSocket.WebSocket): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Adapted from https://github.com/rsocket/rsocket-js/blob/1.0.x-alpha/packages/rsocket-websocket-client/src/WebsocketDuplexConnection.ts
|
|
3
|
+
* Copyright 2021-2022 the original author or authors.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { logger } from '@powersync/lib-services-framework';
|
|
18
|
+
import { Deferred, deserializeFrame, serializeFrame } from 'rsocket-core';
|
|
19
|
+
export class WebsocketDuplexConnection extends Deferred {
|
|
20
|
+
constructor(websocketDuplex, frame, multiplexerDemultiplexerFactory, rawSocket) {
|
|
21
|
+
super();
|
|
22
|
+
this.websocketDuplex = websocketDuplex;
|
|
23
|
+
this.rawSocket = rawSocket;
|
|
24
|
+
this.handleClosed = (e) => {
|
|
25
|
+
this.close(new Error(e.reason || 'WebsocketDuplexConnection: Socket closed unexpectedly.'));
|
|
26
|
+
};
|
|
27
|
+
this.handleError = (e) => {
|
|
28
|
+
logger.error(`Error in WebSocket duplex connection: ${e}`);
|
|
29
|
+
this.close(e.error);
|
|
30
|
+
};
|
|
31
|
+
this.handleMessage = (buffer) => {
|
|
32
|
+
try {
|
|
33
|
+
const frame = deserializeFrame(buffer);
|
|
34
|
+
this.multiplexerDemultiplexer.handle(frame);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.close(error);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
websocketDuplex.on('close', this.handleClosed);
|
|
41
|
+
websocketDuplex.on('error', this.handleError);
|
|
42
|
+
websocketDuplex.on('data', this.handleMessage);
|
|
43
|
+
this.multiplexerDemultiplexer = multiplexerDemultiplexerFactory(frame, this);
|
|
44
|
+
}
|
|
45
|
+
get availability() {
|
|
46
|
+
return this.websocketDuplex.destroyed ? 0 : 1;
|
|
47
|
+
}
|
|
48
|
+
close(error) {
|
|
49
|
+
if (this.done) {
|
|
50
|
+
super.close(error);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.websocketDuplex.removeAllListeners();
|
|
54
|
+
this.websocketDuplex.end();
|
|
55
|
+
super.close(error);
|
|
56
|
+
}
|
|
57
|
+
send(frame) {
|
|
58
|
+
if (this.done) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const buffer = serializeFrame(frame);
|
|
63
|
+
// Work around for this issue
|
|
64
|
+
// https://github.com/websockets/ws/issues/1515
|
|
65
|
+
if (this.rawSocket.readyState == this.rawSocket.CLOSING || this.rawSocket.readyState == this.rawSocket.CLOSED) {
|
|
66
|
+
this.close(new Error('WebSocket is closing'));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this.websocketDuplex.write(buffer);
|
|
70
|
+
}
|
|
71
|
+
catch (ex) {
|
|
72
|
+
this.close(new Error(ex.reason || `Could not write to WebSocket duplex connection: ${ex}`));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
static create(socket, connectionAcceptor, multiplexerDemultiplexerFactory, rawSocket) {
|
|
76
|
+
socket.once('data', async (buffer) => {
|
|
77
|
+
let frame = undefined;
|
|
78
|
+
try {
|
|
79
|
+
frame = deserializeFrame(buffer);
|
|
80
|
+
if (!frame) {
|
|
81
|
+
throw new Error(`Unable to deserialize frame`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (ex) {
|
|
85
|
+
logger.info(`Received error deserializing initial frame buffer. Skipping connection request.`, ex);
|
|
86
|
+
// The initial frame should always be parsable
|
|
87
|
+
return socket.end();
|
|
88
|
+
}
|
|
89
|
+
const connection = new WebsocketDuplexConnection(socket, frame, multiplexerDemultiplexerFactory, rawSocket);
|
|
90
|
+
if (connection.done) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
socket.pause();
|
|
95
|
+
await connectionAcceptor(frame, connection);
|
|
96
|
+
socket.resume();
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
logger.info(`Error accepting connection:`, error);
|
|
100
|
+
connection.close(error);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=WebsocketDuplexConnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsocketDuplexConnection.js","sourceRoot":"","sources":["../../../src/router/transport/WebsocketDuplexConnection.ts"],"names":[],"mappings":"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"}
|
package/dist/router/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import * as micro_router from '@journeyapps-platform/micro-router';
|
|
3
2
|
import * as t from 'ts-codec';
|
|
3
|
+
import { router } from '@powersync/lib-services-framework';
|
|
4
4
|
import { OnExtensionSubscriber, OnNextSubscriber, OnTerminalSubscriber } from 'rsocket-core';
|
|
5
5
|
import { SocketRouterObserver } from './SocketRouterListener.js';
|
|
6
6
|
export declare enum RS_ENDPOINT_TYPE {
|
|
@@ -10,7 +10,9 @@ export declare const RSocketRequestMeta: t.ObjectCodec<{
|
|
|
10
10
|
path: t.IdentityCodec<t.CodecType.String>;
|
|
11
11
|
}>;
|
|
12
12
|
export type RequestMeta = t.Decoded<typeof RSocketRequestMeta>;
|
|
13
|
-
export type ReactiveSocketRouterOptions<C> = {
|
|
13
|
+
export type ReactiveSocketRouterOptions<C> = {
|
|
14
|
+
max_concurrent_connections?: number;
|
|
15
|
+
};
|
|
14
16
|
export type SocketResponder = OnTerminalSubscriber & OnNextSubscriber & OnExtensionSubscriber;
|
|
15
17
|
export type CommonStreamPayload = {
|
|
16
18
|
observer: SocketRouterObserver;
|
|
@@ -19,7 +21,7 @@ export type CommonStreamPayload = {
|
|
|
19
21
|
export type ReactiveStreamPayload<O> = CommonStreamPayload & {
|
|
20
22
|
initialN: number;
|
|
21
23
|
};
|
|
22
|
-
export type IReactiveStream<I = any, O = any, C = any> =
|
|
24
|
+
export type IReactiveStream<I = any, O = any, C = any> = Omit<router.Endpoint<I, O, C, router.EndpointHandlerPayload<I, C> & CommonStreamPayload, router.EndpointHandler<router.EndpointHandlerPayload<I, C> & ReactiveStreamPayload<O>, undefined>>, 'method'> & {
|
|
23
25
|
type: RS_ENDPOINT_TYPE.STREAM;
|
|
24
26
|
/**
|
|
25
27
|
* Decodes raw payload buffer to [I].
|
|
@@ -27,7 +29,7 @@ export type IReactiveStream<I = any, O = any, C = any> = micro_router.Endpoint<I
|
|
|
27
29
|
*/
|
|
28
30
|
decoder?: (rawData?: Buffer) => Promise<I>;
|
|
29
31
|
};
|
|
30
|
-
export type IReactiveStreamInput<I, O, C> = Omit<IReactiveStream<I, O, C>, 'path' | 'type'>;
|
|
32
|
+
export type IReactiveStreamInput<I, O, C> = Omit<IReactiveStream<I, O, C>, 'path' | 'type' | 'method'>;
|
|
31
33
|
export type ReactiveEndpoint = IReactiveStream;
|
|
32
34
|
export type CommonParams<C> = {
|
|
33
35
|
endpoints: Array<ReactiveEndpoint>;
|
package/dist/router/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAO9B,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,sEAAsE;IACtE,qCAAiB,CAAA;AACnB,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM;CACf,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseObserver.js","sourceRoot":"","sources":["../../src/utils/BaseObserver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,MAAM,OAAO,YAAY;IAGvB;QACE,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,gBAAgB,CAAC,QAAoB;QACnC,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC;IAED,gBAAgB,CAAC,EAAiC;QAChD,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE
|
|
1
|
+
{"version":3,"file":"BaseObserver.js","sourceRoot":"","sources":["../../src/utils/BaseObserver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,MAAM,OAAO,YAAY;IAGvB;QACE,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,gBAAgB,CAAC,QAAoB;QACnC,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC;IAED,gBAAgB,CAAC,EAAiC;QAChD,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;YAC5B,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SACvB;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,EAA0C;QACpE,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;YAC5B,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SAC7B;IACH,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/service-rsocket-router",
|
|
3
3
|
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.8",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "FSL-1.1-Apache-2.0",
|
|
@@ -14,20 +14,17 @@
|
|
|
14
14
|
"type": "module",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"rsocket-core": "1.0.0-alpha.3",
|
|
17
|
-
"rsocket-websocket-server": "1.0.0-alpha.3",
|
|
18
|
-
"@journeyapps-platform/micro": "^16.1.0",
|
|
19
|
-
"@journeyapps-platform/micro-authorizers": "^5.2.0",
|
|
20
|
-
"@journeyapps-platform/micro-migrate": "^3.1.0",
|
|
21
|
-
"@journeyapps-platform/micro-router": "^7.0.0",
|
|
22
17
|
"ts-codec": "^1.2.2",
|
|
23
18
|
"uuid": "^9.0.1",
|
|
24
|
-
"ws": "
|
|
19
|
+
"ws": "^8.17.0",
|
|
20
|
+
"@powersync/lib-services-framework": "0.1.0"
|
|
25
21
|
},
|
|
26
22
|
"devDependencies": {
|
|
27
23
|
"@types/uuid": "^9.0.4",
|
|
28
24
|
"@types/ws": "~8.2.0",
|
|
29
25
|
"bson": "^6.6.0",
|
|
30
|
-
"
|
|
26
|
+
"rsocket-websocket-client": "1.0.0-alpha.3",
|
|
27
|
+
"typescript": "~5.2.2",
|
|
31
28
|
"vitest": "^0.34.6"
|
|
32
29
|
},
|
|
33
30
|
"scripts": {
|