r-agency-mesh-client-v1 1.0.3
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/package.json +27 -0
- package/release/index.cjs +207 -0
- package/release/index.d.cts +47 -0
- package/tsconfig.json +26 -0
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "r-agency-mesh-client-v1",
|
|
3
|
+
"author": "Jonny Becker",
|
|
4
|
+
"version": "1.0.3",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"release": "tsup"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"typescript": "~5.7.2",
|
|
14
|
+
"vite": "^6.2.0",
|
|
15
|
+
"tsup": "^8.4.0",
|
|
16
|
+
"ts-node": "^10.9.2",
|
|
17
|
+
"tslib": "^2.8.1"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"axios": "^1.8.4",
|
|
21
|
+
"short-unique-id": "^5.2.2",
|
|
22
|
+
"zod": "^3.24.2"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;// src/classes/client/mesh.client.ts
|
|
2
|
+
var _axios = require('axios'); var _axios2 = _interopRequireDefault(_axios);
|
|
3
|
+
|
|
4
|
+
// src/helper/url.ts
|
|
5
|
+
var mapping = {
|
|
6
|
+
connect: "connect"
|
|
7
|
+
};
|
|
8
|
+
var createMeshUrl = (host, port, type) => {
|
|
9
|
+
const path = _nullishCoalesce(mapping[type], () => ( void 0));
|
|
10
|
+
if (!path) {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
return new URL([`${host}:${port}`, path].join("/"));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/helper/client-id.ts
|
|
17
|
+
var hasMashClientId = () => {
|
|
18
|
+
return !!window.localStorage.getItem("mesh-client-id");
|
|
19
|
+
};
|
|
20
|
+
var setMeshClientId = (id) => {
|
|
21
|
+
const item = {
|
|
22
|
+
id,
|
|
23
|
+
date: (/* @__PURE__ */ new Date()).getTime()
|
|
24
|
+
};
|
|
25
|
+
window.localStorage.setItem("mesh-client-id", JSON.stringify(item));
|
|
26
|
+
};
|
|
27
|
+
var getMeshClientId = () => {
|
|
28
|
+
try {
|
|
29
|
+
const json = window.localStorage.getItem("mesh-client-id");
|
|
30
|
+
if (!json) {
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
return JSON.parse(json);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/classes/client/mesh.client.ts
|
|
40
|
+
var _zod = require('zod');
|
|
41
|
+
|
|
42
|
+
// src/classes/event-manager/event.manager.ts
|
|
43
|
+
var EventManager = (_class = class {constructor() { _class.prototype.__init.call(this); }
|
|
44
|
+
__init() {this.listeners = {}}
|
|
45
|
+
on(eventName, listener) {
|
|
46
|
+
this.listeners[eventName] ??= [];
|
|
47
|
+
_optionalChain([this, 'access', _ => _.listeners, 'access', _2 => _2[eventName], 'optionalAccess', _3 => _3.push, 'call', _4 => _4(listener)]);
|
|
48
|
+
return () => {
|
|
49
|
+
this.off(eventName, listener);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
off(eventName, listener) {
|
|
53
|
+
this.listeners[eventName] ??= [];
|
|
54
|
+
this.listeners[eventName] = _optionalChain([this, 'access', _5 => _5.listeners, 'access', _6 => _6[eventName], 'optionalAccess', _7 => _7.filter, 'call', _8 => _8(
|
|
55
|
+
(l) => l !== listener
|
|
56
|
+
)]);
|
|
57
|
+
}
|
|
58
|
+
emit(eventName, payload) {
|
|
59
|
+
this.listeners[eventName] ??= [];
|
|
60
|
+
_optionalChain([this, 'access', _9 => _9.listeners, 'access', _10 => _10[eventName], 'optionalAccess', _11 => _11.forEach, 'call', _12 => _12((listener) => listener(payload))]);
|
|
61
|
+
}
|
|
62
|
+
}, _class);
|
|
63
|
+
|
|
64
|
+
// src/helper/message.ts
|
|
65
|
+
var parseIncomingMessage = (event) => {
|
|
66
|
+
const type = Object.prototype.toString.call(event.data);
|
|
67
|
+
try {
|
|
68
|
+
switch (type) {
|
|
69
|
+
case "[object ArrayBuffer]":
|
|
70
|
+
return {
|
|
71
|
+
type,
|
|
72
|
+
data: JSON.parse(new TextDecoder().decode(event.data))
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
type
|
|
77
|
+
};
|
|
78
|
+
} catch (e) {
|
|
79
|
+
return {
|
|
80
|
+
type,
|
|
81
|
+
error: e
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// src/classes/websocket/web.socket.client.ts
|
|
87
|
+
var WebSocketClient = (_class2 = class {
|
|
88
|
+
__init2() {this.websocket = void 0}
|
|
89
|
+
constructor() {;_class2.prototype.__init2.call(this);
|
|
90
|
+
}
|
|
91
|
+
connect(config, clientId) {
|
|
92
|
+
const url = new URL(config.websocket.url);
|
|
93
|
+
url.searchParams.set("token", JSON.stringify({
|
|
94
|
+
version: "1.0",
|
|
95
|
+
clientId
|
|
96
|
+
}));
|
|
97
|
+
const websocket = new WebSocket(url.toString());
|
|
98
|
+
websocket.binaryType = "arraybuffer";
|
|
99
|
+
websocket.addEventListener("open", this.open.bind(this));
|
|
100
|
+
websocket.addEventListener("close", this.close.bind(this));
|
|
101
|
+
websocket.addEventListener("message", this.message.bind(this));
|
|
102
|
+
this.websocket = websocket;
|
|
103
|
+
}
|
|
104
|
+
send(payload) {
|
|
105
|
+
try {
|
|
106
|
+
const encoder = new TextEncoder();
|
|
107
|
+
const encoded = encoder.encode(JSON.stringify(payload));
|
|
108
|
+
_optionalChain([this, 'access', _13 => _13.websocket, 'optionalAccess', _14 => _14.send, 'call', _15 => _15(encoded)]);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
const error = e;
|
|
111
|
+
console.log(error.message);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
message(event) {
|
|
115
|
+
const message = parseIncomingMessage(event);
|
|
116
|
+
const data = _nullishCoalesce(message.data, () => ( {}));
|
|
117
|
+
if (data.ping) {
|
|
118
|
+
return this.send({
|
|
119
|
+
pong: true
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
open() {
|
|
124
|
+
this.send({});
|
|
125
|
+
}
|
|
126
|
+
close() {
|
|
127
|
+
}
|
|
128
|
+
}, _class2);
|
|
129
|
+
|
|
130
|
+
// src/classes/client/mesh.client.ts
|
|
131
|
+
var MeshClient = (_class3 = class {
|
|
132
|
+
constructor(config) {;_class3.prototype.__init3.call(this);
|
|
133
|
+
this.config = config;
|
|
134
|
+
this.websocket = new WebSocketClient();
|
|
135
|
+
}
|
|
136
|
+
__init3() {this.events = new EventManager()}
|
|
137
|
+
|
|
138
|
+
connect() {
|
|
139
|
+
return new Promise((resolve) => {
|
|
140
|
+
const validation = _zod.z.object({
|
|
141
|
+
host: _zod.z.string().url(),
|
|
142
|
+
port: _zod.z.number()
|
|
143
|
+
}).safeParse({
|
|
144
|
+
host: this.config.host,
|
|
145
|
+
port: this.config.port
|
|
146
|
+
});
|
|
147
|
+
if (!validation.success) {
|
|
148
|
+
throw new Error("invalid config schema!");
|
|
149
|
+
}
|
|
150
|
+
const url = createMeshUrl(this.config.host, this.config.port, "connect");
|
|
151
|
+
if (!url) {
|
|
152
|
+
throw new Error("mesh connect url not found!");
|
|
153
|
+
}
|
|
154
|
+
_axios2.default.request({
|
|
155
|
+
method: "post",
|
|
156
|
+
url: url.toString(),
|
|
157
|
+
headers: {
|
|
158
|
+
..._nullishCoalesce(this.config.headers, () => ( {})),
|
|
159
|
+
...{
|
|
160
|
+
"x-mesh-host": new URL(this.config.host).host,
|
|
161
|
+
"x-mesh-client-id": _optionalChain([getMeshClientId, 'call', _16 => _16(), 'optionalAccess', _17 => _17.id])
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}).then((response) => {
|
|
165
|
+
this.connected(response.data);
|
|
166
|
+
resolve();
|
|
167
|
+
}).catch(() => {
|
|
168
|
+
throw new Error("connection to mesh-server failed!");
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
connected(response) {
|
|
173
|
+
const success = _nullishCoalesce(response.success, () => ( false));
|
|
174
|
+
const config = response.config;
|
|
175
|
+
const clientId = response.clientId;
|
|
176
|
+
if (!success || !config || !clientId) {
|
|
177
|
+
throw new Error("mesh client config not loaded!");
|
|
178
|
+
}
|
|
179
|
+
if (!hasMashClientId()) {
|
|
180
|
+
setMeshClientId(clientId);
|
|
181
|
+
}
|
|
182
|
+
this.events.emit("connected", {
|
|
183
|
+
config
|
|
184
|
+
});
|
|
185
|
+
this.websocket.connect(config, clientId);
|
|
186
|
+
}
|
|
187
|
+
}, _class3);
|
|
188
|
+
|
|
189
|
+
// src/index.ts
|
|
190
|
+
var useMeshClient = () => {
|
|
191
|
+
const createClient = (config) => {
|
|
192
|
+
if (!window.MeshClient) {
|
|
193
|
+
window.MeshClient = new MeshClient(config);
|
|
194
|
+
}
|
|
195
|
+
return window.MeshClient;
|
|
196
|
+
};
|
|
197
|
+
return {
|
|
198
|
+
createClient
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
var createMeshClient = (config) => {
|
|
202
|
+
return new MeshClient(config);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
exports.createMeshClient = createMeshClient; exports.useMeshClient = useMeshClient;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
interface IMeshClientCreateConfig {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
headers?: Record<string, any>;
|
|
5
|
+
}
|
|
6
|
+
declare global {
|
|
7
|
+
interface Window {
|
|
8
|
+
MeshClient: IMeshClient;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type EventMap = {
|
|
13
|
+
[eventName: string]: any;
|
|
14
|
+
};
|
|
15
|
+
type off = () => void;
|
|
16
|
+
interface EventManagerInt<Events extends EventMap> {
|
|
17
|
+
on<K extends keyof Events>(eventName: K, listener: (payload: Events[K]) => void): off;
|
|
18
|
+
off<K extends keyof Events>(eventName: K, listener: (payload: Events[K]) => void): void;
|
|
19
|
+
emit<K extends keyof Events>(eventName: K, payload?: Events[K]): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface IMeshClientConfig {
|
|
23
|
+
graphql: {
|
|
24
|
+
url: string;
|
|
25
|
+
};
|
|
26
|
+
websocket: {
|
|
27
|
+
url: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type MeshClientEvents = {
|
|
32
|
+
connected: {
|
|
33
|
+
config: IMeshClientConfig;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
interface IMeshClient {
|
|
38
|
+
events: EventManagerInt<MeshClientEvents>;
|
|
39
|
+
connect(): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
declare const useMeshClient: () => {
|
|
43
|
+
createClient: (config: IMeshClientCreateConfig) => IMeshClient;
|
|
44
|
+
};
|
|
45
|
+
declare const createMeshClient: (config: IMeshClientCreateConfig) => IMeshClient;
|
|
46
|
+
|
|
47
|
+
export { createMeshClient, useMeshClient };
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": [
|
|
7
|
+
"ES2020",
|
|
8
|
+
"DOM",
|
|
9
|
+
"DOM.Iterable"
|
|
10
|
+
],
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"moduleDetection": "force",
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedSideEffectImports": true
|
|
22
|
+
},
|
|
23
|
+
"include": [
|
|
24
|
+
"src"
|
|
25
|
+
]
|
|
26
|
+
}
|