crossws 0.1.3 → 0.2.1

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.
Files changed (38) hide show
  1. package/dist/adapters/bun.cjs +24 -24
  2. package/dist/adapters/bun.d.cts +9 -9
  3. package/dist/adapters/bun.d.mts +9 -9
  4. package/dist/adapters/bun.d.ts +9 -9
  5. package/dist/adapters/bun.mjs +21 -21
  6. package/dist/adapters/cloudflare.cjs +20 -17
  7. package/dist/adapters/cloudflare.d.cts +6 -6
  8. package/dist/adapters/cloudflare.d.mts +6 -6
  9. package/dist/adapters/cloudflare.d.ts +6 -6
  10. package/dist/adapters/cloudflare.mjs +16 -13
  11. package/dist/adapters/deno.cjs +17 -17
  12. package/dist/adapters/deno.d.cts +6 -6
  13. package/dist/adapters/deno.d.mts +6 -6
  14. package/dist/adapters/deno.d.ts +6 -6
  15. package/dist/adapters/deno.mjs +14 -14
  16. package/dist/adapters/node.cjs +21 -21
  17. package/dist/adapters/node.d.cts +7 -7
  18. package/dist/adapters/node.d.mts +7 -7
  19. package/dist/adapters/node.d.ts +7 -7
  20. package/dist/adapters/node.mjs +18 -18
  21. package/dist/adapters/uws.cjs +33 -26
  22. package/dist/adapters/uws.d.cts +7 -7
  23. package/dist/adapters/uws.d.mts +7 -7
  24. package/dist/adapters/uws.d.ts +7 -7
  25. package/dist/adapters/uws.mjs +31 -24
  26. package/dist/index.cjs +12 -10
  27. package/dist/index.d.cts +4 -113
  28. package/dist/index.d.mts +4 -113
  29. package/dist/index.d.ts +4 -113
  30. package/dist/index.mjs +7 -5
  31. package/dist/shared/{crossws.a6b0a7cc.mjs → crossws.34cfc8d0.mjs} +31 -42
  32. package/dist/shared/crossws.a2e5c71e.d.cts +112 -0
  33. package/dist/shared/crossws.a2e5c71e.d.mts +112 -0
  34. package/dist/shared/crossws.a2e5c71e.d.ts +112 -0
  35. package/dist/shared/{crossws.6009d265.cjs → crossws.c13afbe7.cjs} +33 -43
  36. package/package.json +2 -2
  37. package/dist/shared/crossws.6f7f02b3.mjs +0 -8
  38. package/dist/shared/crossws.deae10fd.cjs +0 -10
@@ -0,0 +1,112 @@
1
+ declare class WSError extends Error {
2
+ constructor(...args: any[]);
3
+ }
4
+
5
+ declare class Message {
6
+ readonly rawData: any;
7
+ readonly isBinary?: boolean | undefined;
8
+ constructor(rawData: any, isBinary?: boolean | undefined);
9
+ text(): string;
10
+ toString(): string;
11
+ }
12
+
13
+ type ReadyState = 0 | 1 | 2 | 3;
14
+ declare abstract class Peer<AdapterContext = any> implements WSRequest {
15
+ ctx: AdapterContext;
16
+ _subscriptions: Set<string>;
17
+ constructor(ctx: AdapterContext);
18
+ get id(): string | undefined;
19
+ get url(): string;
20
+ get headers(): HeadersInit;
21
+ get readyState(): ReadyState | -1;
22
+ abstract send(message: any, options?: {
23
+ compress?: boolean;
24
+ }): number;
25
+ publish(topic: string, message: any, options?: {
26
+ compress?: boolean;
27
+ }): void;
28
+ subscribe(topic: string): void;
29
+ unsubscribe(topic: string): void;
30
+ toString(): string;
31
+ }
32
+
33
+ type MaybePromise<T> = T | Promise<T>;
34
+ type Caller<T extends Record<string, (...args: any[]) => Promise<any>>, RT = null> = <K extends keyof T>(key: K, ...args: Parameters<T[K]>) => RT extends null ? Promise<ReturnType<T[K]>> : RT;
35
+ interface AdapterOptions {
36
+ resolve?: ResolveHooks;
37
+ hooks?: Hooks;
38
+ adapterHooks?: AdapterHooks;
39
+ }
40
+ type Adapter<AdapterT, Options extends AdapterOptions> = (options?: Options) => AdapterT;
41
+ declare function defineWebSocketAdapter<AdapterT, Options extends AdapterOptions = AdapterOptions>(factory: Adapter<AdapterT, Options>): Adapter<AdapterT, Options>;
42
+ interface CrossWS {
43
+ $callHook: Caller<AdapterHooks>;
44
+ callHook: Caller<Exclude<Hooks, "upgrade">, void>;
45
+ upgrade: (req: WSRequest) => Promise<{
46
+ headers?: HeadersInit;
47
+ }>;
48
+ }
49
+ interface WSRequest {
50
+ readonly url: string;
51
+ readonly headers: HeadersInit;
52
+ }
53
+ declare function defineHooks<T extends Partial<Hooks> = Partial<Hooks>>(hooks: T): T;
54
+ type ResolveHooks = (info: WSRequest | Peer) => Partial<Hooks> | Promise<Partial<Hooks>>;
55
+ type HookFn<ArgsT extends any[] = any, RT = void> = (info: Peer, ...args: ArgsT) => MaybePromise<RT>;
56
+ interface Hooks extends Record<string, HookFn<any[], any>> {
57
+ /** Upgrading */
58
+ upgrade: (req: WSRequest) => MaybePromise<void | {
59
+ headers?: HeadersInit;
60
+ }>;
61
+ /** A message is received */
62
+ message: (peer: Peer, message: Message) => MaybePromise<void>;
63
+ /** A socket is opened */
64
+ open: (peer: Peer) => MaybePromise<void>;
65
+ /** A socket is closed */
66
+ close: (peer: Peer, details: {
67
+ code?: number;
68
+ reason?: string;
69
+ }) => MaybePromise<void>;
70
+ /** An error occurs */
71
+ error: (peer: Peer, error: WSError) => MaybePromise<void>;
72
+ }
73
+ interface AdapterHooks extends Record<string, HookFn<any[], any>> {
74
+ "bun:message": HookFn<[ws: any, message: any]>;
75
+ "bun:open": HookFn<[ws: any]>;
76
+ "bun:close": HookFn<[ws: any]>;
77
+ "bun:drain": HookFn<[]>;
78
+ "bun:error": HookFn<[ws: any, error: any]>;
79
+ "bun:ping": HookFn<[ws: any, data: any]>;
80
+ "bun:pong": HookFn<[ws: any, data: any]>;
81
+ "cloudflare:accept": HookFn<[]>;
82
+ "cloudflare:message": HookFn<[event: any]>;
83
+ "cloudflare:error": HookFn<[event: any]>;
84
+ "cloudflare:close": HookFn<[event: any]>;
85
+ "deno:open": HookFn<[]>;
86
+ "deno:message": HookFn<[event: any]>;
87
+ "deno:close": HookFn<[]>;
88
+ "deno:error": HookFn<[error: any]>;
89
+ "node:open": HookFn<[]>;
90
+ "node:message": HookFn<[data: any, isBinary: boolean]>;
91
+ "node:close": HookFn<[code: number, reason: Buffer]>;
92
+ "node:error": HookFn<[error: any]>;
93
+ "node:ping": HookFn<[data: Buffer]>;
94
+ "node:pong": HookFn<[data: Buffer]>;
95
+ "node:unexpected-response": HookFn<[req: any, res: any]>;
96
+ "node:upgrade": HookFn<[req: any]>;
97
+ "uws:open": HookFn<[ws: any]>;
98
+ "uws:message": HookFn<[ws: any, message: any, isBinary: boolean]>;
99
+ "uws:close": HookFn<[ws: any, code: number, message: any]>;
100
+ "uws:ping": HookFn<[ws: any, message: any]>;
101
+ "uws:pong": HookFn<[ws: any, message: any]>;
102
+ "uws:drain": HookFn<[ws: any]>;
103
+ "uws:upgrade": HookFn<[res: any, req: any, context: any]>;
104
+ "uws:subscription": HookFn<[
105
+ ws: any,
106
+ topic: any,
107
+ newCount: number,
108
+ oldCount: number
109
+ ]>;
110
+ }
111
+
112
+ export { type AdapterOptions as A, type CrossWS as C, type Hooks as H, Message as M, Peer as P, type ResolveHooks as R, WSError as W, type Caller as a, type Adapter as b, type WSRequest as c, defineWebSocketAdapter as d, defineHooks as e, type AdapterHooks as f };
@@ -0,0 +1,112 @@
1
+ declare class WSError extends Error {
2
+ constructor(...args: any[]);
3
+ }
4
+
5
+ declare class Message {
6
+ readonly rawData: any;
7
+ readonly isBinary?: boolean | undefined;
8
+ constructor(rawData: any, isBinary?: boolean | undefined);
9
+ text(): string;
10
+ toString(): string;
11
+ }
12
+
13
+ type ReadyState = 0 | 1 | 2 | 3;
14
+ declare abstract class Peer<AdapterContext = any> implements WSRequest {
15
+ ctx: AdapterContext;
16
+ _subscriptions: Set<string>;
17
+ constructor(ctx: AdapterContext);
18
+ get id(): string | undefined;
19
+ get url(): string;
20
+ get headers(): HeadersInit;
21
+ get readyState(): ReadyState | -1;
22
+ abstract send(message: any, options?: {
23
+ compress?: boolean;
24
+ }): number;
25
+ publish(topic: string, message: any, options?: {
26
+ compress?: boolean;
27
+ }): void;
28
+ subscribe(topic: string): void;
29
+ unsubscribe(topic: string): void;
30
+ toString(): string;
31
+ }
32
+
33
+ type MaybePromise<T> = T | Promise<T>;
34
+ type Caller<T extends Record<string, (...args: any[]) => Promise<any>>, RT = null> = <K extends keyof T>(key: K, ...args: Parameters<T[K]>) => RT extends null ? Promise<ReturnType<T[K]>> : RT;
35
+ interface AdapterOptions {
36
+ resolve?: ResolveHooks;
37
+ hooks?: Hooks;
38
+ adapterHooks?: AdapterHooks;
39
+ }
40
+ type Adapter<AdapterT, Options extends AdapterOptions> = (options?: Options) => AdapterT;
41
+ declare function defineWebSocketAdapter<AdapterT, Options extends AdapterOptions = AdapterOptions>(factory: Adapter<AdapterT, Options>): Adapter<AdapterT, Options>;
42
+ interface CrossWS {
43
+ $callHook: Caller<AdapterHooks>;
44
+ callHook: Caller<Exclude<Hooks, "upgrade">, void>;
45
+ upgrade: (req: WSRequest) => Promise<{
46
+ headers?: HeadersInit;
47
+ }>;
48
+ }
49
+ interface WSRequest {
50
+ readonly url: string;
51
+ readonly headers: HeadersInit;
52
+ }
53
+ declare function defineHooks<T extends Partial<Hooks> = Partial<Hooks>>(hooks: T): T;
54
+ type ResolveHooks = (info: WSRequest | Peer) => Partial<Hooks> | Promise<Partial<Hooks>>;
55
+ type HookFn<ArgsT extends any[] = any, RT = void> = (info: Peer, ...args: ArgsT) => MaybePromise<RT>;
56
+ interface Hooks extends Record<string, HookFn<any[], any>> {
57
+ /** Upgrading */
58
+ upgrade: (req: WSRequest) => MaybePromise<void | {
59
+ headers?: HeadersInit;
60
+ }>;
61
+ /** A message is received */
62
+ message: (peer: Peer, message: Message) => MaybePromise<void>;
63
+ /** A socket is opened */
64
+ open: (peer: Peer) => MaybePromise<void>;
65
+ /** A socket is closed */
66
+ close: (peer: Peer, details: {
67
+ code?: number;
68
+ reason?: string;
69
+ }) => MaybePromise<void>;
70
+ /** An error occurs */
71
+ error: (peer: Peer, error: WSError) => MaybePromise<void>;
72
+ }
73
+ interface AdapterHooks extends Record<string, HookFn<any[], any>> {
74
+ "bun:message": HookFn<[ws: any, message: any]>;
75
+ "bun:open": HookFn<[ws: any]>;
76
+ "bun:close": HookFn<[ws: any]>;
77
+ "bun:drain": HookFn<[]>;
78
+ "bun:error": HookFn<[ws: any, error: any]>;
79
+ "bun:ping": HookFn<[ws: any, data: any]>;
80
+ "bun:pong": HookFn<[ws: any, data: any]>;
81
+ "cloudflare:accept": HookFn<[]>;
82
+ "cloudflare:message": HookFn<[event: any]>;
83
+ "cloudflare:error": HookFn<[event: any]>;
84
+ "cloudflare:close": HookFn<[event: any]>;
85
+ "deno:open": HookFn<[]>;
86
+ "deno:message": HookFn<[event: any]>;
87
+ "deno:close": HookFn<[]>;
88
+ "deno:error": HookFn<[error: any]>;
89
+ "node:open": HookFn<[]>;
90
+ "node:message": HookFn<[data: any, isBinary: boolean]>;
91
+ "node:close": HookFn<[code: number, reason: Buffer]>;
92
+ "node:error": HookFn<[error: any]>;
93
+ "node:ping": HookFn<[data: Buffer]>;
94
+ "node:pong": HookFn<[data: Buffer]>;
95
+ "node:unexpected-response": HookFn<[req: any, res: any]>;
96
+ "node:upgrade": HookFn<[req: any]>;
97
+ "uws:open": HookFn<[ws: any]>;
98
+ "uws:message": HookFn<[ws: any, message: any, isBinary: boolean]>;
99
+ "uws:close": HookFn<[ws: any, code: number, message: any]>;
100
+ "uws:ping": HookFn<[ws: any, message: any]>;
101
+ "uws:pong": HookFn<[ws: any, message: any]>;
102
+ "uws:drain": HookFn<[ws: any]>;
103
+ "uws:upgrade": HookFn<[res: any, req: any, context: any]>;
104
+ "uws:subscription": HookFn<[
105
+ ws: any,
106
+ topic: any,
107
+ newCount: number,
108
+ oldCount: number
109
+ ]>;
110
+ }
111
+
112
+ export { type AdapterOptions as A, type CrossWS as C, type Hooks as H, Message as M, Peer as P, type ResolveHooks as R, WSError as W, type Caller as a, type Adapter as b, type WSRequest as c, defineWebSocketAdapter as d, defineHooks as e, type AdapterHooks as f };
@@ -1,52 +1,34 @@
1
1
  'use strict';
2
2
 
3
- function defineWebSocketAdapter(factory) {
4
- return factory;
5
- }
6
-
7
- function createCrossWS(hooks, options) {
8
- const _callHook = options.resolve ? async function(name, info, ...args) {
9
- const hooks2 = await options.resolve?.(info);
10
- const hook = hooks2?.[name];
11
- return hook?.(info, ...args);
12
- } : void 0;
3
+ function createCrossWS(opts = {}) {
4
+ const resolveHook = async (req, name) => {
5
+ const hooks = await opts.resolve?.(req);
6
+ return hooks?.[name];
7
+ };
13
8
  return {
14
- async $(name, ...args) {
15
- await Promise.all([hooks.$?.(name, ...args), _callHook?.(name, ...args)]);
9
+ // WS Hooks
10
+ async callHook(name, ...args) {
11
+ await opts.hooks?.[name]?.apply(void 0, args);
12
+ const hook = await resolveHook(args[0], name);
13
+ await hook?.apply(void 0, args);
16
14
  },
15
+ // Upgrade
17
16
  async upgrade(req) {
18
- const upgradeResults = await Promise.all([
19
- hooks.upgrade?.(req),
20
- _callHook?.("upgrade", req)
17
+ const [res1, res2] = await Promise.all([
18
+ opts.hooks?.upgrade?.(req),
19
+ await resolveHook(req, "upgrade").then((h) => h?.(req))
21
20
  ]);
22
- const headers = /* @__PURE__ */ Object.create(null);
23
- for (const result of upgradeResults) {
24
- if (result?.headers) {
25
- Object.assign(headers, result.headers);
21
+ const headers = new Headers(res1?.headers);
22
+ if (res2?.headers) {
23
+ for (const [key, value] of new Headers(res2?.headers)) {
24
+ headers.append(key, value);
26
25
  }
27
26
  }
28
27
  return { headers };
29
28
  },
30
- async message(peer, message) {
31
- await Promise.all([
32
- hooks.message?.(peer, message),
33
- _callHook?.("message", peer, message)
34
- ]);
35
- },
36
- async open(peer) {
37
- await Promise.all([hooks.open?.(peer), _callHook?.("open", peer)]);
38
- },
39
- async close(peer, { code, reason }) {
40
- await Promise.all([
41
- hooks.close?.(peer, { code, reason }),
42
- _callHook?.("close", peer, { code, reason })
43
- ]);
44
- },
45
- async error(peer, error) {
46
- await Promise.all([
47
- hooks.error?.(peer, error),
48
- _callHook?.("error", peer, error)
49
- ]);
29
+ // Adapter hook
30
+ $callHook(name, ...args) {
31
+ return opts.adapterHooks?.[name]?.apply(void 0, args);
50
32
  }
51
33
  };
52
34
  }
@@ -80,7 +62,7 @@ function isPlainObject(value) {
80
62
  return true;
81
63
  }
82
64
 
83
- class WSMessage {
65
+ class Message {
84
66
  constructor(rawData, isBinary) {
85
67
  this.rawData = rawData;
86
68
  this.isBinary = isBinary;
@@ -116,7 +98,7 @@ const ReadyStateMap = {
116
98
  2: "closing",
117
99
  3: "closed"
118
100
  };
119
- class WSPeer {
101
+ class Peer {
120
102
  constructor(ctx) {
121
103
  this.ctx = ctx;
122
104
  __publicField(this, "_subscriptions", /* @__PURE__ */ new Set());
@@ -149,8 +131,16 @@ class WSPeer {
149
131
  }
150
132
  }
151
133
 
152
- exports.WSMessage = WSMessage;
153
- exports.WSPeer = WSPeer;
134
+ function defineWebSocketAdapter(factory) {
135
+ return factory;
136
+ }
137
+ function defineHooks(hooks) {
138
+ return hooks;
139
+ }
140
+
141
+ exports.Message = Message;
142
+ exports.Peer = Peer;
154
143
  exports.createCrossWS = createCrossWS;
144
+ exports.defineHooks = defineHooks;
155
145
  exports.defineWebSocketAdapter = defineWebSocketAdapter;
156
146
  exports.toBufferLike = toBufferLike;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crossws",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "Cross-platform WebSocket Servers for Node.js, Deno, Bun and Cloudflare Workers",
5
5
  "repository": "unjs/crossws",
6
6
  "license": "MIT",
@@ -96,7 +96,7 @@
96
96
  "eslint-config-unjs": "^0.2.1",
97
97
  "h3": "^1.10.1",
98
98
  "jiti": "^1.21.0",
99
- "listhen": "^1.6.0",
99
+ "listhen": "^1.7.0",
100
100
  "prettier": "^3.2.4",
101
101
  "typescript": "^5.3.3",
102
102
  "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.33.0",
@@ -1,8 +0,0 @@
1
- class WebSocketError extends Error {
2
- constructor(...args) {
3
- super(...args);
4
- this.name = "WebSocketError";
5
- }
6
- }
7
-
8
- export { WebSocketError as W };
@@ -1,10 +0,0 @@
1
- 'use strict';
2
-
3
- class WebSocketError extends Error {
4
- constructor(...args) {
5
- super(...args);
6
- this.name = "WebSocketError";
7
- }
8
- }
9
-
10
- exports.WebSocketError = WebSocketError;