This issue proposes that an effort should be made to re-write the core set of rsocket-js packages from Flow to TypeScript, with a focus on adopting a "small core" mentality when designing the projects public API.
This issue is to serve as:
- Documentation of the proposal that was discussed and decided upon
- A means of tracking progress towards implementing the proposal
Motivation
TypeScript in Favor of Flow
TypeScript is a proven solution for authoring JavaScript libraries for use in NodeJs and browser environments, and will provide a number of benefits to the project:
- Continued development & support from Microsoft
- Large community adoption
- Easier and more familiar tooling
- Types can be published from source without authoring additional
@types
In addition to the above, in a recent post on the Flow Type blog, the Flow team described a refocusing of the projects priorities towards Facebook's internal needs. This is a signal that Flow may not be a suitable solution for projects outside of Facebook's internal infrastructure and ecosystem.
Small Core
New APIs and paradigms should be introduced to adopt a "small core" mentality, with core rsocket-js packages providing only the basic building blocks and implementations for the RSocket protocol. APIs should be easily extendable/composable to support additional packages that can later provide functionality outside of implementing the RSocket protocol, for example, an RxJS interface.
This "small core" approach is intended to assist with maintainability of the project, as well as ease of support for satisfying feature requests through extensions and "addon" packages.
Other RSocket implementations, such as RSocket-Swift, have benefited to a degree from this approach.
Serialization and Encoding
In conformance with the "small core" goal of this initiative, support for payload data encoding should be reduced down to transmitting instances of Buffer, rather than supporting a wide variety of data and metadata payload serialization and encodings. This stance is in contrast to the current support provided by @rsocket packages, where support for serializing objects to JSON and other formats is provided by interfaces such as JsonSerializer, and encoding is provided by interfaces such as BufferEncoders.
Support for user friendly translation of objects and other structures to/from JSON and other serialization formats can be accomplished via extension packages, rather than as a core feature of rsocket-js.
Reactive APIs
rsocket-js has historically leveraged a Reactive Streams implementation (rsocket-flowable) both internally, and as its public API. This implementation has historically been published under @rsocekt/rsocket-flowable. Moving forward, rsocket-js will move away from @rsocket/rsocket-flowable as a key feature of its public API, and instead focus on exposing a core set of Stream APIs that satisfy the core requirements of the RSocket protocol, while also promoting composition and extension with other Reactive Streams implementations, such as RxJS and reactive-streams-js.
Interfaces example:
export interface Cancellable {
cancel(): void;
}
export interface Requestable {
request(requestN: number): void;
}
export interface OnExtensionSubscriber {
onExtension(
extendedType: number,
content: Buffer | null | undefined,
canBeIgnored: boolean
): void;
}
export interface OnNextSubscriber {
onNext(payload: Payload, isComplete: boolean): void;
}
export interface OnTerminalSubscriber {
onError(error: Error): void;
onComplete(): void;
}
The intention of this change is two fold:
- Simplify the internal implementation details of the core
rsocket-js libraries
- Allow for consumers and integrators to easily extend
rsocket-js with their Reactive Streams implementation of choice
Desired solution
Core RSocket protocol feature support, and APIs implementations needed:
TODO: complete list of necessary core protocol features
Considered alternatives
N/A
Additional context
Major Version Change
Because of the breaking API changes that this effort will introduce, the version of all @rsocket scoped packages who's APIs are modified will be incremented to an initial major version release of 1.0.
Issues & pull requests related to this work should be/are tagged with the 1.0 tag.
Work in progress
Work for this effort is ongoing in the dev branch.
API Example
const connector = new RSocketConnector({
transport: new TcpClientTransport({
connectionOptions: {
host: "127.0.0.1",
port: 9090,
},
}),
});
const rsocket = await connector.bind();
await new Promise((resolve, reject) =>
rsocket.requestResponse(
{
data: Buffer.from("Hello World"),
},
{
onError: (e) => reject(e),
onNext: (payload, isComplete) => {
console.log(
`payload[data: ${payload.data}; metadata: ${payload.metadata}]|${isComplete}`
);
resolve(payload);
},
onComplete: () => { },
onExtension: () => { },
cancel: () => { },
request: () => { },
}
)
);
This issue proposes that an effort should be made to re-write the core set of
rsocket-jspackages from Flow to TypeScript, with a focus on adopting a "small core" mentality when designing the projects public API.This issue is to serve as:
Motivation
TypeScript in Favor of Flow
TypeScript is a proven solution for authoring JavaScript libraries for use in NodeJs and browser environments, and will provide a number of benefits to the project:
@typesIn addition to the above, in a recent post on the Flow Type blog, the Flow team described a refocusing of the projects priorities towards Facebook's internal needs. This is a signal that Flow may not be a suitable solution for projects outside of Facebook's internal infrastructure and ecosystem.
Small Core
New APIs and paradigms should be introduced to adopt a "small core" mentality, with core
rsocket-jspackages providing only the basic building blocks and implementations for the RSocket protocol. APIs should be easily extendable/composable to support additional packages that can later provide functionality outside of implementing the RSocket protocol, for example, anRxJSinterface.This "small core" approach is intended to assist with maintainability of the project, as well as ease of support for satisfying feature requests through extensions and "addon" packages.
Other RSocket implementations, such as RSocket-Swift, have benefited to a degree from this approach.
Serialization and Encoding
In conformance with the "small core" goal of this initiative, support for payload data encoding should be reduced down to transmitting instances of
Buffer, rather than supporting a wide variety ofdataandmetadatapayload serialization and encodings. This stance is in contrast to the current support provided by@rsocketpackages, where support for serializing objects to JSON and other formats is provided by interfaces such asJsonSerializer, and encoding is provided by interfaces such asBufferEncoders.Support for user friendly translation of objects and other structures to/from
JSONand other serialization formats can be accomplished via extension packages, rather than as a core feature ofrsocket-js.Reactive APIs
rsocket-jshas historically leveraged a Reactive Streams implementation (rsocket-flowable) both internally, and as its public API. This implementation has historically been published under@rsocekt/rsocket-flowable. Moving forward,rsocket-jswill move away from@rsocket/rsocket-flowableas a key feature of its public API, and instead focus on exposing a core set of Stream APIs that satisfy the core requirements of the RSocket protocol, while also promoting composition and extension with other Reactive Streams implementations, such as RxJS and reactive-streams-js.Interfaces example:
The intention of this change is two fold:
rsocket-jslibrariesrsocket-jswith their Reactive Streams implementation of choiceDesired solution
Core RSocket protocol feature support, and APIs implementations needed:
RSocketConnectorAPITODO: complete list of necessary core protocol features
Considered alternatives
N/A
Additional context
Major Version Change
Because of the breaking API changes that this effort will introduce, the version of all
@rsocketscoped packages who's APIs are modified will be incremented to an initial major version release of1.0.Issues & pull requests related to this work should be/are tagged with the
1.0tag.Work in progress
Work for this effort is ongoing in the
devbranch.API Example