Compare commits

...

59 Commits

Author SHA1 Message Date
2e4adba867 3.0.1 2024-04-18 21:49:13 +02:00
a6530e9752 fix(core): update 2024-04-18 21:49:13 +02:00
7163c1dc67 update documentation 2024-04-14 19:01:25 +02:00
c2f4efd33d 3.0.0 2023-08-06 16:52:04 +02:00
bc7a828124 BREAKING CHANGE(core): update 2023-08-06 16:52:03 +02:00
f62497ce48 2.0.28 2023-08-06 16:37:40 +02:00
64e5f30bad fix(core): update 2023-08-06 16:37:39 +02:00
1b41d5e3ad 2.0.27 2023-08-05 12:00:28 +02:00
c5954aa880 fix(core): update 2023-08-05 12:00:27 +02:00
b58d8084e9 2.0.26 2023-08-05 11:46:40 +02:00
f765e60e1f fix(core): update 2023-08-05 11:46:39 +02:00
b726669c4b 2.0.25 2023-08-04 16:22:40 +02:00
4f0066b5ca fix(core): update 2023-08-04 16:22:39 +02:00
0edc903900 2.0.24 2023-03-29 19:02:10 +02:00
fa41192377 fix(core): update 2023-03-29 19:02:10 +02:00
725e3c65c6 2.0.23 2023-03-29 16:29:58 +02:00
4e9108f7df fix(core): update 2023-03-29 16:29:58 +02:00
420d634e83 2.0.22 2023-03-29 13:47:03 +02:00
eb596e5dd8 fix(core): update 2023-03-29 13:47:03 +02:00
5748bd8280 2.0.21 2023-03-29 13:45:34 +02:00
4e8ea21df2 fix(core): update 2023-03-29 13:45:33 +02:00
6f4be3baaa 2.0.20 2023-03-20 19:23:20 +01:00
a484060888 fix(core): update 2023-03-20 19:23:20 +01:00
c1b15daaca 2.0.19 2023-03-20 17:06:33 +01:00
f9397feaf0 fix(core): update 2023-03-20 17:06:33 +01:00
889ec9c8ec 2.0.18 2022-12-29 12:17:59 +01:00
5d460cf002 fix(core): update 2022-12-29 12:17:58 +01:00
5e6ec0d311 2.0.17 2022-12-28 20:31:03 +01:00
dd834590cc fix(core): update 2022-12-28 20:31:03 +01:00
96b7354dae 2.0.16 2022-12-28 18:54:57 +01:00
3a5533c4fe fix(core): update 2022-12-28 18:54:57 +01:00
1f5f84763d 2.0.15 2022-12-28 15:15:19 +01:00
6474112275 fix(core): update 2022-12-28 15:15:19 +01:00
a46c0cf395 2.0.14 2022-12-28 15:14:48 +01:00
8be5c352f4 fix(core): update 2022-12-28 15:14:48 +01:00
caaf947a46 2.0.13 2022-12-28 15:05:53 +01:00
2ec88494be fix(core): update 2022-12-28 15:05:53 +01:00
b80346d742 2.0.12 2022-10-26 22:39:40 +02:00
aced21a968 fix(core): update 2022-10-26 22:39:39 +02:00
fa40e3a5dc 2.0.11 2022-10-26 18:59:50 +02:00
9bb0008381 fix(core): update 2022-10-26 18:59:49 +02:00
67bbea8811 2.0.10 2022-10-26 14:23:14 +02:00
dc826cb65a fix(core): update 2022-10-26 14:23:14 +02:00
1266a814c6 2.0.9 2022-10-26 11:00:07 +02:00
25a7397548 fix(core): update 2022-10-26 11:00:06 +02:00
5009bec70c 2.0.8 2022-10-26 10:55:09 +02:00
d8d7b135f7 fix(core): update 2022-10-26 10:55:08 +02:00
9738d88ec7 2.0.7 2022-10-26 10:54:37 +02:00
9d7f433685 fix(core): update 2022-10-26 10:54:36 +02:00
fc1124fb16 2.0.6 2022-10-26 10:54:19 +02:00
5e5f493dfa fix(core): update 2022-10-26 10:54:18 +02:00
899a46f9de 2.0.5 2022-08-02 10:21:16 +02:00
1412a06f4c fix(core): update 2022-08-02 10:21:15 +02:00
51e6c5cf0e 2.0.4 2022-05-13 08:14:10 +02:00
8d7eb3ff5f fix(core): update 2022-05-13 08:14:09 +02:00
a82f8ccc26 2.0.3 2022-03-29 15:38:38 +02:00
d934f4b53b fix(core): update 2022-03-29 15:38:37 +02:00
54b8a692ba 2.0.2 2022-03-25 00:42:50 +01:00
2f39b5662d fix(core): update 2022-03-25 00:42:50 +01:00
16 changed files with 4797 additions and 19212 deletions

View File

@@ -12,29 +12,25 @@ stages:
- release
- metadata
before_script:
- pnpm install -g pnpm
- pnpm install -g @shipzone/npmci
- npmci npm prepare
# ====================
# security stage
# ====================
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
only:
- tags
tags:
- lossless
- docker
- notpriv
auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --production --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=prod --production
- npmci command npm config set registry https://registry.npmjs.org
- npmci command pnpm audit --audit-level=high --prod
tags:
- lossless
- docker
allow_failure: true
@@ -42,11 +38,10 @@ auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=dev
- npmci command pnpm audit --audit-level=high --dev
tags:
- lossless
- docker
allow_failure: true
@@ -57,7 +52,6 @@ auditDevDependencies:
testStable:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
@@ -68,10 +62,9 @@ testStable:
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
- npmci npm build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
@@ -97,10 +90,9 @@ codequality:
only:
- tags
script:
- npmci command npm install -g tslint typescript
- npmci command npm install -g typescript
- npmci npm prepare
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- lossless
- docker
@@ -120,11 +112,9 @@ trigger:
pages:
stage: metadata
script:
- npmci node install lts
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command tsdoc
- npmci command npm run buildDocs
tags:
- lossless
- docker

24
.vscode/launch.json vendored
View File

@@ -2,28 +2,10 @@
"version": "0.2.0",
"configurations": [
{
"name": "current file",
"type": "node",
"command": "npm test",
"name": "Run npm test",
"request": "launch",
"args": [
"${relativeFile}"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": "test.ts",
"type": "node",
"request": "launch",
"args": [
"test/test.ts"
],
"runtimeArgs": ["-r", "@gitzone/tsrun"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"internalConsoleOptions": "openOnSessionStart"
"type": "node-terminal"
}
]
}

View File

@@ -2,17 +2,28 @@
"gitzone": {
"projectType": "npm",
"module": {
"githost": "gitlab.com",
"gitscope": "apiglobal",
"githost": "code.foss.global",
"gitscope": "api.global",
"gitrepo": "typedsocket",
"description": "a typedrequest extension supporting websockets",
"npmPackagename": "@apiglobal/typedsocket",
"description": "A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.",
"npmPackagename": "@api.global/typedsocket",
"license": "MIT",
"projectDomain": "api.global"
"projectDomain": "api.global",
"keywords": [
"WebSocket",
"Type Safety",
"Real-time Communication",
"Client-Server Architecture",
"TypeScript",
"Networking"
]
}
},
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
},
"tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
}
}

19023
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
{
"name": "@apiglobal/typedsocket",
"version": "2.0.1",
"name": "@api.global/typedsocket",
"version": "3.0.1",
"private": false,
"description": "a typedrequest extension supporting websockets",
"description": "A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"type": "module",
@@ -10,24 +10,27 @@
"license": "MIT",
"scripts": {
"test": "(tstest test/ --web)",
"build": "(tsbuild --web --allowimplicitany)"
"build": "(tsbuild --web --allowimplicitany --skiplibcheck)",
"buildDocs": "tsdoc"
},
"devDependencies": {
"@gitzone/tsbuild": "^2.1.61",
"@gitzone/tsbundle": "^1.0.101",
"@gitzone/tstest": "^1.0.69",
"@pushrocks/smartenv": "^5.0.0",
"@pushrocks/tapbundle": "^5.0.3",
"@types/node": "^17.0.23",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.15.0"
"@git.zone/tsbuild": "^2.1.66",
"@git.zone/tsbundle": "^2.0.8",
"@git.zone/tsrun": "^1.2.44",
"@git.zone/tstest": "^1.0.77",
"@push.rocks/smartenv": "^5.0.12",
"@push.rocks/tapbundle": "^5.0.23",
"@types/node": "^20.12.7"
},
"dependencies": {
"@apiglobal/typedrequest": "^2.0.0",
"@apiglobal/typedrequest-interfaces": "^1.0.15",
"@pushrocks/isohash": "^2.0.0",
"@pushrocks/smartsocket": "^2.0.4",
"@pushrocks/smartstring": "^4.0.2"
"@api.global/typedrequest": "^3.0.21",
"@api.global/typedrequest-interfaces": "^3.0.18",
"@push.rocks/isohash": "^2.0.0",
"@push.rocks/smartjson": "^5.0.19",
"@push.rocks/smartrx": "^3.0.7",
"@push.rocks/smartsocket": "^2.0.25",
"@push.rocks/smartstring": "^4.0.15",
"@push.rocks/smarturl": "^3.0.5"
},
"browserslist": [
"last 1 chrome versions"
@@ -43,5 +46,13 @@
"cli.js",
"npmextra.json",
"readme.md"
],
"keywords": [
"WebSocket",
"Type Safety",
"Real-time Communication",
"Client-Server Architecture",
"TypeScript",
"Networking"
]
}

4460
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

1
readme.hints.md Normal file
View File

@@ -0,0 +1 @@

174
readme.md
View File

@@ -1,43 +1,159 @@
# @apiglobal/typedsocket
# @api.global/typedsocket
a typedrequest extension supporting websockets
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@apiglobal/typedsocket)
* [gitlab.com (source)](https://gitlab.com/apiglobal/typedsocket)
* [github.com (source mirror)](https://github.com/apiglobal/typedsocket)
* [docs (typedoc)](https://apiglobal.gitlab.io/typedsocket/)
## Install
To install `@api.global/typedsocket` in your project, run the following command using npm:
## Status for master
```bash
npm install @api.global/typedsocket --save
```
Status Category | Status Badge
-- | --
GitLab Pipelines | [![pipeline status](https://gitlab.com/apiglobal/typedsocket/badges/master/pipeline.svg)](https://lossless.cloud)
GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/apiglobal/typedsocket/badges/master/coverage.svg)](https://lossless.cloud)
npm | [![npm downloads per month](https://badgen.net/npm/dy/@apiglobal/typedsocket)](https://lossless.cloud)
Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/apiglobal/typedsocket)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@apiglobal/typedsocket)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@apiglobal/typedsocket)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@apiglobal/typedsocket)](https://lossless.cloud)
Platform support | [![Supports Windows 10](https://badgen.net/badge/supports%20Windows%2010/yes/green?icon=windows)](https://lossless.cloud) [![Supports Mac OS X](https://badgen.net/badge/supports%20Mac%20OS%20X/yes/green?icon=apple)](https://lossless.cloud)
For Yarn users:
```bash
yarn add @api.global/typedsocket
```
## Usage
Use TypeScript for best in class intellisense.
To utilize `@api.global/typedsocket` effectively, let's explore how to integrate it into a project with TypeScript. This guide provides comprehensive usage scenarios, highlighting all features of the module. `@api.global/typedsocket` extends the capabilities of `typedrequest` by integrating websocket support, allowing for real-time, bidirectional communication between a client and server.
TypedSocket is the typedrequest you love, just in a bidirectional way.
### Getting Started
See the following examples from our test for reference:
#### Prerequisites
## Contribution
Before diving into examples, ensure you have the following:
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
- A basic understanding of TypeScript and Node.js.
- An existing project set up with TypeScript.
- `@api.global/typedrequest` and its dependencies installed in your project.
For further information read the linked docs at the top of this readme.
#### Initialization
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
First, let's import the required modules and initialize our server and client instances.
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)
**Server Side:**
Within your server-side code, import and set up `TypedSocket` to create a websocket server.
```typescript
import { TypedSocket } from '@api.global/typedsocket';
import * as typedrequest from '@api.global/typedrequest';
// Initialize your TypedRouter
const typedRouter = new typedrequest.TypedRouter();
// Create the TypedSocket server
const server = await TypedSocket.createServer(typedRouter);
// Optionally, you can provide a smartexpressServerArg if you have an existing SmartExpress server
```
**Client Side:**
On the client side, initialize `TypedSocket` to connect to the websocket server.
```typescript
import { TypedSocket } from '@api.global/typedsocket';
// Assuming server is at http://localhost:3000
const client = await TypedSocket.createClient(typedRouter, 'http://localhost:3000');
```
### Defining Typed Requests
`@api.global/typedsocket` leverages `typedrequest` for type-safe requests and responses. Here's how you can define and handle typed requests:
**Defining a Typed Request Interface:**
Define an interface for the request and its corresponding response.
```typescript
interface ExampleRequest extends typedrequestInterfaces.ITypedRequest {
method: 'exampleMethod';
request: {
message: string;
};
response: {
reply: string;
};
}
```
**Handling Requests on the Server:**
Add a typed handler for the request in your `TypedRouter`.
```typescript
typedRouter.addTypedHandler<ExampleRequest>(
new typedrequest.TypedHandler('exampleMethod', async (requestData) => {
return {
reply: `Server received: ${requestData.message}`,
};
})
);
```
### Sending Requests from the Client
Use the client instance to send a request to the server and await a response.
```typescript
const exampleRequest = client.createTypedRequest<ExampleRequest>('exampleMethod');
const response = await exampleRequest.fire({
message: 'Hello from client!',
});
console.log(response.reply); // "Server received: Hello from client!"
```
### Advanced Usage
#### Tagging Connections
For more refined control, especially in scenarios with multiple clients, you can tag connections for targeted communication.
```typescript
// Add a tag to a client
client.addTag('role', 'admin');
// On the server, find connections with the tag
const adminConnections = await server.findAllTargetConnectionsByTag('role', 'admin');
// Send a message to all admin connections
for (const adminConnection of adminConnections) {
const request = server.createTypedRequest<ExampleRequest>('exampleMethod', adminConnection);
await request.fire({
message: 'Message to admins',
});
}
```
#### Handling Reconnections
`TypedSocket` automatically attempts to reconnect in the event of connection loss. Ensure your server and client logic accounts for reconnection, especially for maintaining state or re-subscribing to necessary events.
### Conclusion
Implementing `@api.global/typedsocket` provides a type-safe, real-time communication layer for your TypeScript applications, extending the functionality of `typedrequest` into the realm of websockets. This guide covered initialization, defining typed requests, sending requests, and advanced usage patterns like tagging connections and handling reconnections.
Integrating `@api.global/typedsocket` into your project harnesses the power of websockets with the benefits of type safety and structured request/response patterns, enabling more reliable and maintainable real-time applications.
## License and Legal Information
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
### Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
### Company Information
Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@pushrocks/tapbundle';
import { tap, expect } from '@push.rocks/tapbundle';
import * as typedsocket from '../ts/index.js';

View File

@@ -1,20 +1,21 @@
import { expect, tap } from '@pushrocks/tapbundle';
import * as typedrequest from '@apiglobal/typedrequest';
import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces';
import { expect, tap } from '@push.rocks/tapbundle';
import * as typedrequest from '@api.global/typedrequest';
import * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
import * as typedsocket from '../ts/index.js';
interface IRequest_Client_Server extends typedrequestInterfaces.implementsTR<
typedrequestInterfaces.ITypedRequest,
IRequest_Client_Server
> {
interface IRequest_Client_Server
extends typedrequestInterfaces.implementsTR<
typedrequestInterfaces.ITypedRequest,
IRequest_Client_Server
> {
method: 'sayhi';
request: {
greeting: string;
};
response: {
answer: string
}
answer: string;
};
}
let testTypedSocketServer: typedsocket.TypedSocket;
@@ -23,45 +24,52 @@ let testTypedSocketClient: typedsocket.TypedSocket;
const testTypedRouter = new typedrequest.TypedRouter();
tap.test('should add some handlers', async () => {
testTypedRouter.addTypedHandler<IRequest_Client_Server>(new typedrequest.TypedHandler('sayhi', async requestData => {
return {
answer: `ok, got it : ${requestData.greeting}`
}
}));
})
testTypedRouter.addTypedHandler<IRequest_Client_Server>(
new typedrequest.TypedHandler('sayhi', async (requestData) => {
return {
answer: `ok, got it : ${requestData.greeting}`,
};
})
);
});
tap.test('should create Server and Client', async (tools) => {
testTypedSocketServer = await typedsocket.TypedSocket.createServer(testTypedRouter);
testTypedSocketClient = await typedsocket.TypedSocket.createClient(testTypedRouter, 'http://localhost:3000');
testTypedSocketClient = await typedsocket.TypedSocket.createClient(
testTypedRouter,
'http://localhost:3000'
);
console.log('test: waiting 5 seconds');
await tools.delayFor(5000);
await testTypedSocketServer.stop();
// lets create another server
testTypedSocketServer = await typedsocket.TypedSocket.createServer(testTypedRouter);
// lets see if auto reconnect works
console.log('test: waiting 21 seconds for reconnect');
await tools.delayFor(21000);
});
tap.test('should process messages from both sides', async () => {
const myServerSideTypedRequest = testTypedSocketServer.createTypedRequest<IRequest_Client_Server>('sayhi');
const myClientSideTypedRequest = testTypedSocketClient.createTypedRequest<IRequest_Client_Server>('sayhi');
const myServerSideTypedRequest =
testTypedSocketServer.createTypedRequest<IRequest_Client_Server>('sayhi');
const myClientSideTypedRequest =
testTypedSocketClient.createTypedRequest<IRequest_Client_Server>('sayhi');
const response = await myClientSideTypedRequest.fire({
greeting: 'that is a greeting from the client'
greeting: 'that is a greeting from the client',
});
console.log(response);
const response2 = await myServerSideTypedRequest.fire({
greeting: 'that is a greeting from the server'
greeting: 'that is a greeting from the server',
});
console.log(response2);
})
});
tap.test('should disconnect', async (tools) => {
await testTypedSocketClient.stop();
await testTypedSocketServer.stop();
tools.delayFor(1000).then(() => process.exit(0));
})
});
tap.start();

8
ts/00_commitinfo_data.ts Normal file
View File

@@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@api.global/typedsocket',
version: '3.0.1',
description: 'A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.'
}

View File

@@ -1 +1 @@
export * from './typedsocket.classes.typedsocket.js';
export * from './typedsocket.classes.typedsocket.js';

View File

@@ -11,7 +11,7 @@ export class TypedSocket {
* creates a typedsocket server
* note: this will fail in browser environments as server libs are not bundled.
*/
public static async createServer (
public static async createServer(
typedrouterArg: plugins.typedrequest.TypedRouter,
smartexpressServerArg?: any
): Promise<TypedSocket> {
@@ -34,7 +34,7 @@ export class TypedSocket {
const typedsocket = new TypedSocket(
'server',
typedrouterArg,
async <T extends plugins.typedrequestInterfaces.ITypedRequest> (
async <T extends plugins.typedrequestInterfaces.ITypedRequest>(
dataArg: T,
targetConnectionArg?: plugins.smartsocket.SocketConnection
): Promise<T> => {
@@ -43,16 +43,18 @@ export class TypedSocket {
console.log(
'Since no targetConnection was supplied and there is only one active one present, choosing that one automatically'
);
targetConnectionArg = smartsocketServer.socketConnections.getArray()[ 0 ];
targetConnectionArg = smartsocketServer.socketConnections.getArray()[0];
} else {
throw new Error('you need to specify the wanted targetConnection. Currently no target is selectable automatically.');
throw new Error(
'you need to specify the wanted targetConnection. Currently no target is selectable automatically.'
);
}
}
const response: T = await smartsocketServer.clientCall(
const response: T = (await smartsocketServer.clientCall(
'processMessage',
dataArg,
targetConnectionArg
) as any;
)) as any;
return response;
},
smartsocketServer
@@ -62,7 +64,7 @@ export class TypedSocket {
return typedsocket;
}
public static async createClient (
public static async createClient(
typedrouterArg: plugins.typedrequest.TypedRouter,
serverUrlArg: string,
aliasArg = 'clientArg'
@@ -74,8 +76,8 @@ export class TypedSocket {
port: domain.port || 3000,
url: `${domain.nodeParsedUrl.protocol}//${domain.nodeParsedUrl.hostname}`,
autoReconnect: true,
}
console.log(`starting typedsocket with the following settings:`)
};
console.log(`starting typedsocket with the following settings:`);
console.log(socketOptions);
const smartsocketClient = new plugins.smartsocket.SmartsocketClient(socketOptions);
smartsocketClient.addSocketFunction(
@@ -89,27 +91,39 @@ export class TypedSocket {
const typedsocket = new TypedSocket(
'client',
typedrouterArg,
async <T extends plugins.typedrequestInterfaces.ITypedRequest> (dataArg: T): Promise<T> => {
const response: T = (smartsocketClient.serverCall('processMessage', dataArg) as any) as T;
async <T extends plugins.typedrequestInterfaces.ITypedRequest>(dataArg: T): Promise<T> => {
const response: T = smartsocketClient.serverCall('processMessage', dataArg) as any as T;
return response;
},
smartsocketClient
);
console.log(`typedsocket triggering smartsocket to connect...`);
const before = Date.now();
await smartsocketClient.connect();
console.log(`typedsocket triggered smartsocket connected in ${Date.now() - before}ms!!!`)
return typedsocket;
}
public static useWindowLocationOriginUrl = () => {
const windowLocationResult = plugins.smarturl.Smarturl.createFromUrl(globalThis.location.origin).toString();
return windowLocationResult;
}
// INSTANCE
public side: TTypedSocketSide;
public typedrouter: plugins.typedrequest.TypedRouter;
public get eventSubject(): plugins.smartrx.rxjs.Subject<plugins.smartsocket.TConnectionStatus> {
return this.socketServerOrClient.eventSubject;
}
private postMethod: plugins.typedrequest.IPostMethod &
((
typedRequestPostObject: plugins.typedrequestInterfaces.ITypedRequest,
socketConnectionArg?: plugins.smartsocket.SocketConnection
) => Promise<plugins.typedrequestInterfaces.ITypedRequest>);
private socketServerOrClient: plugins.smartsocket.Smartsocket | plugins.smartsocket.SmartsocketClient;
private socketServerOrClient:
| plugins.smartsocket.Smartsocket
| plugins.smartsocket.SmartsocketClient;
constructor(
sideArg: TTypedSocketSide,
typedrouterArg: plugins.typedrequest.TypedRouter,
@@ -122,19 +136,25 @@ export class TypedSocket {
this.socketServerOrClient = socketServerOrClientArg;
}
public addTag (keyArg: string, payloadArg: any) {
if (this.side === 'client' && this.socketServerOrClient instanceof plugins.smartsocket.SmartsocketClient) {
public addTag<T extends plugins.typedrequestInterfaces.ITag = any>(
nameArg: T['name'],
payloadArg: T['payload']
) {
if (
this.side === 'client' &&
this.socketServerOrClient instanceof plugins.smartsocket.SmartsocketClient
) {
this.socketServerOrClient.socketConnection.addTag({
id: keyArg,
payload: payloadArg
})
id: nameArg,
payload: payloadArg,
});
} else {
throw new Error('tagging is only supported on clients');
}
}
public createTypedRequest<T extends plugins.typedrequestInterfaces.ITypedRequest> (
methodName: T[ 'method' ],
public createTypedRequest<T extends plugins.typedrequestInterfaces.ITypedRequest>(
methodName: T['method'],
targetConnection?: plugins.smartsocket.SocketConnection
): plugins.typedrequest.TypedRequest<T> {
const typedrequest = new plugins.typedrequest.TypedRequest<T>(
@@ -152,9 +172,9 @@ export class TypedSocket {
/**
* returns all matching target connection
* @param asyncFindFuncArg
* @returns
* @returns
*/
public async findAllTargetConnections (
public async findAllTargetConnections(
asyncFindFuncArg: (connectionArg: plugins.smartsocket.SocketConnection) => Promise<boolean>
) {
if (this.socketServerOrClient instanceof plugins.smartsocket.Smartsocket) {
@@ -173,33 +193,41 @@ export class TypedSocket {
/**
* returns a single target connection by returning the first one of all matching ones
* @param asyncFindFuncArg
* @returns
* @returns
*/
public async findTargetConnection (
public async findTargetConnection(
asyncFindFuncArg: (connectionArg: plugins.smartsocket.SocketConnection) => Promise<boolean>
) {
const allMatching = await this.findAllTargetConnections(asyncFindFuncArg);
return allMatching[ 0 ];
return allMatching[0];
}
public async findAllTargetConnectionsByTag (keyArg: string, payloadArg?: any) {
return this.findAllTargetConnections(async socketConnectionArg => {
public async findAllTargetConnectionsByTag<
TTag extends plugins.typedrequestInterfaces.ITag = any
>(keyArg: TTag['name'], payloadArg?: TTag['payload']) {
return this.findAllTargetConnections(async (socketConnectionArg) => {
let result: boolean;
if (!payloadArg) {
result = !!(await socketConnectionArg.getTagById(keyArg));
} else {
result = !!((await socketConnectionArg.getTagById(keyArg)).payload === payloadArg);
result = !!(
plugins.smartjson.stringify((await socketConnectionArg.getTagById(keyArg))?.payload) ===
plugins.smartjson.stringify(payloadArg)
);
}
return result;
})
});
}
public async findTargetConnectionByTag (keyArg: string, payloadArg?: any) {
const allResults = await this.findAllTargetConnectionsByTag(keyArg, payloadArg)
return allResults[ 0 ];
public async findTargetConnectionByTag<TTag extends plugins.typedrequestInterfaces.ITag = any>(
keyArg: TTag['name'],
payloadArg?: TTag['payload']
) {
const allResults = await this.findAllTargetConnectionsByTag(keyArg, payloadArg);
return allResults[0];
}
public async stop () {
await this.socketServerOrClient.stop()
public async stop() {
await this.socketServerOrClient.stop();
}
}

View File

@@ -1,19 +1,15 @@
// @apiglobal scope
import * as typedrequest from '@apiglobal/typedrequest';
import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces';
import * as typedrequest from '@api.global/typedrequest';
import * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
export {
typedrequest,
typedrequestInterfaces,
}
export { typedrequest, typedrequestInterfaces };
// @pushrocks scope
import * as isohash from '@pushrocks/isohash';
import * as smartsocket from '@pushrocks/smartsocket';
import * as smartstring from '@pushrocks/smartstring';
import * as isohash from '@push.rocks/isohash';
import * as smartjson from '@push.rocks/smartjson';
import * as smartrx from '@push.rocks/smartrx';
import * as smartsocket from '@push.rocks/smartsocket';
import * as smartstring from '@push.rocks/smartstring';
import * as smarturl from '@push.rocks/smarturl';
export {
isohash,
smartsocket,
smartstring
}
export { isohash, smartjson, smartrx, smartsocket, smartstring, smarturl };

14
tsconfig.json Normal file
View File

@@ -0,0 +1,14 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true
},
"exclude": [
"dist_*/**/*.d.ts"
]
}

View File

@@ -1,17 +0,0 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}