@playcraft/common 0.0.2

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 (162) hide show
  1. package/README.md +13 -0
  2. package/dist/auth/index.d.ts +4 -0
  3. package/dist/auth/index.d.ts.map +1 -0
  4. package/dist/auth/index.js +4 -0
  5. package/dist/auth/index.js.map +1 -0
  6. package/dist/auth/jwt.d.ts +18 -0
  7. package/dist/auth/jwt.d.ts.map +1 -0
  8. package/dist/auth/jwt.js +47 -0
  9. package/dist/auth/jwt.js.map +1 -0
  10. package/dist/auth/jwt.test.d.ts +2 -0
  11. package/dist/auth/jwt.test.d.ts.map +1 -0
  12. package/dist/auth/jwt.test.js +13 -0
  13. package/dist/auth/jwt.test.js.map +1 -0
  14. package/dist/auth/local-dev.d.ts +27 -0
  15. package/dist/auth/local-dev.d.ts.map +1 -0
  16. package/dist/auth/local-dev.js +38 -0
  17. package/dist/auth/local-dev.js.map +1 -0
  18. package/dist/auth/types.d.ts +7 -0
  19. package/dist/auth/types.d.ts.map +1 -0
  20. package/dist/auth/types.js +2 -0
  21. package/dist/auth/types.js.map +1 -0
  22. package/dist/constants.d.ts +28 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/constants.js +28 -0
  25. package/dist/constants.js.map +1 -0
  26. package/dist/database/index.d.ts +4 -0
  27. package/dist/database/index.d.ts.map +1 -0
  28. package/dist/database/index.js +4 -0
  29. package/dist/database/index.js.map +1 -0
  30. package/dist/database/postgres-adapter.d.ts +8 -0
  31. package/dist/database/postgres-adapter.d.ts.map +1 -0
  32. package/dist/database/postgres-adapter.js +11 -0
  33. package/dist/database/postgres-adapter.js.map +1 -0
  34. package/dist/database/schema.d.ts +919 -0
  35. package/dist/database/schema.d.ts.map +1 -0
  36. package/dist/database/schema.js +70 -0
  37. package/dist/database/schema.js.map +1 -0
  38. package/dist/database/sqlite-adapter.d.ts +11 -0
  39. package/dist/database/sqlite-adapter.d.ts.map +1 -0
  40. package/dist/database/sqlite-adapter.js +78 -0
  41. package/dist/database/sqlite-adapter.js.map +1 -0
  42. package/dist/index.d.ts +10 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +10 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/messenger/index.d.ts +4 -0
  47. package/dist/messenger/index.d.ts.map +1 -0
  48. package/dist/messenger/index.js +4 -0
  49. package/dist/messenger/index.js.map +1 -0
  50. package/dist/messenger/protocol.d.ts +6 -0
  51. package/dist/messenger/protocol.d.ts.map +1 -0
  52. package/dist/messenger/protocol.js +17 -0
  53. package/dist/messenger/protocol.js.map +1 -0
  54. package/dist/messenger/server.d.ts +66 -0
  55. package/dist/messenger/server.d.ts.map +1 -0
  56. package/dist/messenger/server.js +249 -0
  57. package/dist/messenger/server.js.map +1 -0
  58. package/dist/messenger/server.test.d.ts +2 -0
  59. package/dist/messenger/server.test.d.ts.map +1 -0
  60. package/dist/messenger/server.test.js +66 -0
  61. package/dist/messenger/server.test.js.map +1 -0
  62. package/dist/messenger/types.d.ts +32 -0
  63. package/dist/messenger/types.d.ts.map +1 -0
  64. package/dist/messenger/types.js +2 -0
  65. package/dist/messenger/types.js.map +1 -0
  66. package/dist/models/asset.d.ts +57 -0
  67. package/dist/models/asset.d.ts.map +1 -0
  68. package/dist/models/asset.js +33 -0
  69. package/dist/models/asset.js.map +1 -0
  70. package/dist/models/converters.d.ts +11 -0
  71. package/dist/models/converters.d.ts.map +1 -0
  72. package/dist/models/converters.js +25 -0
  73. package/dist/models/converters.js.map +1 -0
  74. package/dist/models/converters.test.d.ts +2 -0
  75. package/dist/models/converters.test.d.ts.map +1 -0
  76. package/dist/models/converters.test.js +18 -0
  77. package/dist/models/converters.test.js.map +1 -0
  78. package/dist/models/index.d.ts +5 -0
  79. package/dist/models/index.d.ts.map +1 -0
  80. package/dist/models/index.js +5 -0
  81. package/dist/models/index.js.map +1 -0
  82. package/dist/models/playcanvas-compat.d.ts +30 -0
  83. package/dist/models/playcanvas-compat.d.ts.map +1 -0
  84. package/dist/models/playcanvas-compat.js +30 -0
  85. package/dist/models/playcanvas-compat.js.map +1 -0
  86. package/dist/models/project.d.ts +28 -0
  87. package/dist/models/project.d.ts.map +1 -0
  88. package/dist/models/project.js +17 -0
  89. package/dist/models/project.js.map +1 -0
  90. package/dist/models/scene.d.ts +52 -0
  91. package/dist/models/scene.d.ts.map +1 -0
  92. package/dist/models/scene.js +49 -0
  93. package/dist/models/scene.js.map +1 -0
  94. package/dist/models/scene.test.d.ts +2 -0
  95. package/dist/models/scene.test.d.ts.map +1 -0
  96. package/dist/models/scene.test.js +12 -0
  97. package/dist/models/scene.test.js.map +1 -0
  98. package/dist/sharedb/index.d.ts +4 -0
  99. package/dist/sharedb/index.d.ts.map +1 -0
  100. package/dist/sharedb/index.js +4 -0
  101. package/dist/sharedb/index.js.map +1 -0
  102. package/dist/sharedb/middleware.d.ts +2 -0
  103. package/dist/sharedb/middleware.d.ts.map +1 -0
  104. package/dist/sharedb/middleware.js +2 -0
  105. package/dist/sharedb/middleware.js.map +1 -0
  106. package/dist/sharedb/server.d.ts +60 -0
  107. package/dist/sharedb/server.d.ts.map +1 -0
  108. package/dist/sharedb/server.js +542 -0
  109. package/dist/sharedb/server.js.map +1 -0
  110. package/dist/sharedb/server.test.d.ts +2 -0
  111. package/dist/sharedb/server.test.d.ts.map +1 -0
  112. package/dist/sharedb/server.test.js +59 -0
  113. package/dist/sharedb/server.test.js.map +1 -0
  114. package/dist/sharedb/snapshot.d.ts +8 -0
  115. package/dist/sharedb/snapshot.d.ts.map +1 -0
  116. package/dist/sharedb/snapshot.js +2 -0
  117. package/dist/sharedb/snapshot.js.map +1 -0
  118. package/dist/storage/cos.d.ts +25 -0
  119. package/dist/storage/cos.d.ts.map +1 -0
  120. package/dist/storage/cos.js +104 -0
  121. package/dist/storage/cos.js.map +1 -0
  122. package/dist/storage/index.d.ts +18 -0
  123. package/dist/storage/index.d.ts.map +1 -0
  124. package/dist/storage/index.js +63 -0
  125. package/dist/storage/index.js.map +1 -0
  126. package/dist/storage/interface.d.ts +19 -0
  127. package/dist/storage/interface.d.ts.map +1 -0
  128. package/dist/storage/interface.js +2 -0
  129. package/dist/storage/interface.js.map +1 -0
  130. package/dist/storage/local.d.ts +16 -0
  131. package/dist/storage/local.d.ts.map +1 -0
  132. package/dist/storage/local.js +57 -0
  133. package/dist/storage/local.js.map +1 -0
  134. package/dist/utils/env.d.ts +2 -0
  135. package/dist/utils/env.d.ts.map +1 -0
  136. package/dist/utils/env.js +10 -0
  137. package/dist/utils/env.js.map +1 -0
  138. package/dist/utils/index.d.ts +3 -0
  139. package/dist/utils/index.d.ts.map +1 -0
  140. package/dist/utils/index.js +3 -0
  141. package/dist/utils/index.js.map +1 -0
  142. package/dist/utils/logger.d.ts +8 -0
  143. package/dist/utils/logger.d.ts.map +1 -0
  144. package/dist/utils/logger.js +10 -0
  145. package/dist/utils/logger.js.map +1 -0
  146. package/dist/websocket/connection.d.ts +4 -0
  147. package/dist/websocket/connection.d.ts.map +1 -0
  148. package/dist/websocket/connection.js +9 -0
  149. package/dist/websocket/connection.js.map +1 -0
  150. package/dist/websocket/heartbeat.d.ts +3 -0
  151. package/dist/websocket/heartbeat.d.ts.map +1 -0
  152. package/dist/websocket/heartbeat.js +16 -0
  153. package/dist/websocket/heartbeat.js.map +1 -0
  154. package/dist/websocket/index.d.ts +4 -0
  155. package/dist/websocket/index.d.ts.map +1 -0
  156. package/dist/websocket/index.js +4 -0
  157. package/dist/websocket/index.js.map +1 -0
  158. package/dist/websocket/server.d.ts +12 -0
  159. package/dist/websocket/server.d.ts.map +1 -0
  160. package/dist/websocket/server.js +12 -0
  161. package/dist/websocket/server.js.map +1 -0
  162. package/package.json +79 -0
@@ -0,0 +1,59 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { ShareDBRealtimeServer } from './server.js';
3
+ describe('ShareDBRealtimeServer', () => {
4
+ it('createHealthHandler returns 200 with JSON status for GET /health', () => {
5
+ return new Promise((resolve, reject) => {
6
+ const rt = new ShareDBRealtimeServer({});
7
+ const handler = rt.createHealthHandler();
8
+ const req = { method: 'GET', url: '/health' };
9
+ const res = {
10
+ statusCode: 0,
11
+ setHeader: () => { },
12
+ end(body) {
13
+ try {
14
+ expect(this.statusCode).toBe(200);
15
+ const data = JSON.parse(body);
16
+ expect(data).toHaveProperty('uptime');
17
+ expect(data).toHaveProperty('connections');
18
+ expect(data).toHaveProperty('memory');
19
+ expect(data).toHaveProperty('timestamp');
20
+ rt.close();
21
+ resolve();
22
+ }
23
+ catch (e) {
24
+ rt.close();
25
+ reject(e);
26
+ }
27
+ },
28
+ };
29
+ handler(req, res);
30
+ });
31
+ });
32
+ it('createHealthHandler returns 404 for GET /other', () => {
33
+ return new Promise((resolve, reject) => {
34
+ const rt = new ShareDBRealtimeServer({});
35
+ const handler = rt.createHealthHandler();
36
+ const req = { method: 'GET', url: '/other' };
37
+ const res = {
38
+ statusCode: 0,
39
+ end() {
40
+ try {
41
+ expect(this.statusCode).toBe(404);
42
+ rt.close();
43
+ resolve();
44
+ }
45
+ catch (e) {
46
+ rt.close();
47
+ reject(e);
48
+ }
49
+ },
50
+ };
51
+ handler(req, res);
52
+ });
53
+ });
54
+ it('close() cleans up without throwing', () => {
55
+ const rt = new ShareDBRealtimeServer({});
56
+ expect(() => rt.close()).not.toThrow();
57
+ });
58
+ });
59
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/sharedb/server.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export type SnapshotStore = {
2
+ save: (collection: string, id: string, version: number, data: unknown) => Promise<void>;
3
+ load: (collection: string, id: string) => Promise<{
4
+ version: number;
5
+ data: unknown;
6
+ } | null>;
7
+ };
8
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/sharedb/snapshot.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CAC9F,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/sharedb/snapshot.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import type { StorageProvider } from './interface.js';
2
+ /**
3
+ * 腾讯云 COS 存储实现
4
+ *
5
+ * 注意:此实现需要安装 cos-nodejs-sdk-v5 依赖
6
+ * pnpm add cos-nodejs-sdk-v5
7
+ */
8
+ export declare class CosStorage implements StorageProvider {
9
+ private readonly bucket;
10
+ private readonly region;
11
+ private readonly secretId;
12
+ private readonly secretKey;
13
+ constructor(config: {
14
+ secretId: string;
15
+ secretKey: string;
16
+ bucket: string;
17
+ region: string;
18
+ });
19
+ save(key: string, buffer: Buffer): Promise<string>;
20
+ read(key: string): Promise<Buffer | null>;
21
+ delete(key: string): Promise<boolean>;
22
+ exists(key: string): Promise<boolean>;
23
+ getUrl(key: string, filename?: string): string;
24
+ }
25
+ //# sourceMappingURL=cos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cos.d.ts","sourceRoot":"","sources":["../../src/storage/cos.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,eAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGvB,MAAM,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB;IAgBK,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBlD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAuBzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe3C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;CAQ/C"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * 腾讯云 COS 存储实现
3
+ *
4
+ * 注意:此实现需要安装 cos-nodejs-sdk-v5 依赖
5
+ * pnpm add cos-nodejs-sdk-v5
6
+ */
7
+ export class CosStorage {
8
+ bucket;
9
+ region;
10
+ secretId;
11
+ secretKey;
12
+ // private cos: any; // COS SDK instance
13
+ constructor(config) {
14
+ this.secretId = config.secretId;
15
+ this.secretKey = config.secretKey;
16
+ this.bucket = config.bucket;
17
+ this.region = config.region;
18
+ // TODO: 初始化 COS SDK
19
+ // const COS = require('cos-nodejs-sdk-v5');
20
+ // this.cos = new COS({
21
+ // SecretId: this.secretId,
22
+ // SecretKey: this.secretKey,
23
+ // });
24
+ console.log(`[storage] COS storage initialized for bucket: ${this.bucket}`);
25
+ }
26
+ async save(key, buffer) {
27
+ // TODO: 实现 COS 上传
28
+ // return new Promise((resolve, reject) => {
29
+ // this.cos.putObject({
30
+ // Bucket: this.bucket,
31
+ // Region: this.region,
32
+ // Key: key,
33
+ // Body: buffer,
34
+ // }, (err: any, data: any) => {
35
+ // if (err) {
36
+ // reject(err);
37
+ // } else {
38
+ // resolve(this.getUrl(key));
39
+ // }
40
+ // });
41
+ // });
42
+ throw new Error('COS storage not implemented yet. Please install cos-nodejs-sdk-v5 and implement this method.');
43
+ }
44
+ async read(key) {
45
+ // TODO: 实现 COS 下载
46
+ // return new Promise((resolve, reject) => {
47
+ // this.cos.getObject({
48
+ // Bucket: this.bucket,
49
+ // Region: this.region,
50
+ // Key: key,
51
+ // }, (err: any, data: any) => {
52
+ // if (err) {
53
+ // if (err.statusCode === 404) {
54
+ // resolve(null);
55
+ // } else {
56
+ // reject(err);
57
+ // }
58
+ // } else {
59
+ // resolve(data.Body);
60
+ // }
61
+ // });
62
+ // });
63
+ throw new Error('COS storage not implemented yet.');
64
+ }
65
+ async delete(key) {
66
+ // TODO: 实现 COS 删除
67
+ // return new Promise((resolve, reject) => {
68
+ // this.cos.deleteObject({
69
+ // Bucket: this.bucket,
70
+ // Region: this.region,
71
+ // Key: key,
72
+ // }, (err: any) => {
73
+ // if (err) {
74
+ // reject(err);
75
+ // } else {
76
+ // resolve(true);
77
+ // }
78
+ // });
79
+ // });
80
+ throw new Error('COS storage not implemented yet.');
81
+ }
82
+ async exists(key) {
83
+ // TODO: 实现 COS 存在检查
84
+ // return new Promise((resolve) => {
85
+ // this.cos.headObject({
86
+ // Bucket: this.bucket,
87
+ // Region: this.region,
88
+ // Key: key,
89
+ // }, (err: any) => {
90
+ // resolve(!err);
91
+ // });
92
+ // });
93
+ throw new Error('COS storage not implemented yet.');
94
+ }
95
+ getUrl(key, filename) {
96
+ // 返回 COS 公开访问 URL
97
+ const baseUrl = `https://${this.bucket}.cos.${this.region}.myqcloud.com`;
98
+ if (filename) {
99
+ return `${baseUrl}/${key}?response-content-disposition=inline;filename=${encodeURIComponent(filename)}`;
100
+ }
101
+ return `${baseUrl}/${key}`;
102
+ }
103
+ }
104
+ //# sourceMappingURL=cos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cos.js","sourceRoot":"","sources":["../../src/storage/cos.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACJ,MAAM,CAAS;IACf,MAAM,CAAS;IACf,QAAQ,CAAS;IACjB,SAAS,CAAS;IACnC,wCAAwC;IAExC,YAAY,MAKX;QACC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE5B,oBAAoB;QACpB,4CAA4C;QAC5C,uBAAuB;QACvB,6BAA6B;QAC7B,+BAA+B;QAC/B,MAAM;QAEN,OAAO,CAAC,GAAG,CAAC,iDAAiD,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,MAAc;QACpC,kBAAkB;QAClB,4CAA4C;QAC5C,yBAAyB;QACzB,2BAA2B;QAC3B,2BAA2B;QAC3B,gBAAgB;QAChB,oBAAoB;QACpB,kCAAkC;QAClC,iBAAiB;QACjB,qBAAqB;QACrB,eAAe;QACf,mCAAmC;QACnC,QAAQ;QACR,QAAQ;QACR,MAAM;QAEN,MAAM,IAAI,KAAK,CAAC,8FAA8F,CAAC,CAAC;IAClH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,kBAAkB;QAClB,4CAA4C;QAC5C,yBAAyB;QACzB,2BAA2B;QAC3B,2BAA2B;QAC3B,gBAAgB;QAChB,kCAAkC;QAClC,iBAAiB;QACjB,sCAAsC;QACtC,yBAAyB;QACzB,iBAAiB;QACjB,uBAAuB;QACvB,UAAU;QACV,eAAe;QACf,4BAA4B;QAC5B,QAAQ;QACR,QAAQ;QACR,MAAM;QAEN,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,kBAAkB;QAClB,4CAA4C;QAC5C,4BAA4B;QAC5B,2BAA2B;QAC3B,2BAA2B;QAC3B,gBAAgB;QAChB,uBAAuB;QACvB,iBAAiB;QACjB,qBAAqB;QACrB,eAAe;QACf,uBAAuB;QACvB,QAAQ;QACR,QAAQ;QACR,MAAM;QAEN,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,oBAAoB;QACpB,oCAAoC;QACpC,0BAA0B;QAC1B,2BAA2B;QAC3B,2BAA2B;QAC3B,gBAAgB;QAChB,uBAAuB;QACvB,qBAAqB;QACrB,QAAQ;QACR,MAAM;QAEN,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,QAAiB;QACnC,kBAAkB;QAClB,MAAM,OAAO,GAAG,WAAW,IAAI,CAAC,MAAM,QAAQ,IAAI,CAAC,MAAM,eAAe,CAAC;QACzE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,GAAG,OAAO,IAAI,GAAG,iDAAiD,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1G,CAAC;QACD,OAAO,GAAG,OAAO,IAAI,GAAG,EAAE,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ export * from './interface.js';
2
+ export * from './local.js';
3
+ export * from './cos.js';
4
+ import type { StorageConfig, StorageProvider } from './interface.js';
5
+ /**
6
+ * 创建存储提供者
7
+ */
8
+ export declare function createStorage(config: StorageConfig): StorageProvider;
9
+ /**
10
+ * 获取全局存储实例(单例模式)
11
+ * 从环境变量读取配置
12
+ */
13
+ export declare function getStorage(): StorageProvider;
14
+ /**
15
+ * 重置存储实例(用于测试)
16
+ */
17
+ export declare function resetStorage(): void;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AAIzB,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIrE;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAYpE;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAkC5C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
@@ -0,0 +1,63 @@
1
+ export * from './interface.js';
2
+ export * from './local.js';
3
+ export * from './cos.js';
4
+ import { LocalStorage } from './local.js';
5
+ import { CosStorage } from './cos.js';
6
+ let storageInstance = null;
7
+ /**
8
+ * 创建存储提供者
9
+ */
10
+ export function createStorage(config) {
11
+ if (config.type === 'cos') {
12
+ return new CosStorage({
13
+ secretId: config.secretId,
14
+ secretKey: config.secretKey,
15
+ bucket: config.bucket,
16
+ region: config.region,
17
+ });
18
+ }
19
+ // 默认使用本地存储
20
+ return new LocalStorage(config);
21
+ }
22
+ /**
23
+ * 获取全局存储实例(单例模式)
24
+ * 从环境变量读取配置
25
+ */
26
+ export function getStorage() {
27
+ if (!storageInstance) {
28
+ const type = process.env.STORAGE_TYPE || 'local';
29
+ if (type === 'cos') {
30
+ const secretId = process.env.COS_SECRET_ID || '';
31
+ const secretKey = process.env.COS_SECRET_KEY || '';
32
+ const bucket = process.env.COS_BUCKET || '';
33
+ const region = process.env.COS_REGION || 'ap-guangzhou';
34
+ if (!secretId || !secretKey || !bucket) {
35
+ throw new Error('COS configuration is incomplete. Please set COS_SECRET_ID, COS_SECRET_KEY, and COS_BUCKET.');
36
+ }
37
+ storageInstance = createStorage({
38
+ type: 'cos',
39
+ secretId,
40
+ secretKey,
41
+ bucket,
42
+ region,
43
+ });
44
+ }
45
+ else {
46
+ const localPath = process.env.STORAGE_LOCAL_PATH || '.data/uploads';
47
+ const baseUrl = process.env.STORAGE_BASE_URL || '/api/files';
48
+ storageInstance = createStorage({
49
+ type: 'local',
50
+ localPath,
51
+ baseUrl,
52
+ });
53
+ }
54
+ }
55
+ return storageInstance;
56
+ }
57
+ /**
58
+ * 重置存储实例(用于测试)
59
+ */
60
+ export function resetStorage() {
61
+ storageInstance = null;
62
+ }
63
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,IAAI,eAAe,GAA2B,IAAI,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,IAAI,UAAU,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC;IAED,WAAW;IACX,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC;QAEjD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;YACjD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,cAAc,CAAC;YAExD,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,4FAA4F,CAAC,CAAC;YAChH,CAAC;YAED,eAAe,GAAG,aAAa,CAAC;gBAC9B,IAAI,EAAE,KAAK;gBACX,QAAQ;gBACR,SAAS;gBACT,MAAM;gBACN,MAAM;aACP,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,eAAe,CAAC;YACpE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,YAAY,CAAC;YAE7D,eAAe,GAAG,aAAa,CAAC;gBAC9B,IAAI,EAAE,OAAO;gBACb,SAAS;gBACT,OAAO;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface StorageProvider {
2
+ save(key: string, buffer: Buffer): Promise<string>;
3
+ read(key: string): Promise<Buffer | null>;
4
+ delete(key: string): Promise<boolean>;
5
+ exists(key: string): Promise<boolean>;
6
+ getUrl(key: string, filename?: string): string;
7
+ }
8
+ export type StorageConfig = {
9
+ type: 'local';
10
+ localPath: string;
11
+ baseUrl?: string;
12
+ } | {
13
+ type: 'cos';
14
+ secretId: string;
15
+ secretKey: string;
16
+ bucket: string;
17
+ region: string;
18
+ };
19
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChD;AAED,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/storage/interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import type { StorageConfig, StorageProvider } from './interface.js';
2
+ type LocalStorageConfig = Extract<StorageConfig, {
3
+ type: 'local';
4
+ }>;
5
+ export declare class LocalStorage implements StorageProvider {
6
+ private readonly config;
7
+ constructor(config: LocalStorageConfig);
8
+ private resolveKey;
9
+ save(key: string, buffer: Buffer): Promise<string>;
10
+ read(key: string): Promise<Buffer | null>;
11
+ delete(key: string): Promise<boolean>;
12
+ exists(key: string): Promise<boolean>;
13
+ getUrl(key: string, filename?: string): string;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAErE,KAAK,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEpE,qBAAa,YAAa,YAAW,eAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,kBAAkB;IAEvD,OAAO,CAAC,UAAU;IAIZ,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IASzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU3C,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;CAM/C"}
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ export class LocalStorage {
4
+ config;
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ resolveKey(key) {
9
+ return path.join(this.config.localPath, key);
10
+ }
11
+ async save(key, buffer) {
12
+ const p = this.resolveKey(key);
13
+ await fs.mkdir(path.dirname(p), { recursive: true });
14
+ await fs.writeFile(p, buffer);
15
+ return this.getUrl(key);
16
+ }
17
+ async read(key) {
18
+ try {
19
+ return await fs.readFile(this.resolveKey(key));
20
+ }
21
+ catch (e) {
22
+ if (e?.code === 'ENOENT')
23
+ return null;
24
+ throw e;
25
+ }
26
+ }
27
+ async delete(key) {
28
+ try {
29
+ await fs.unlink(this.resolveKey(key));
30
+ return true;
31
+ }
32
+ catch (e) {
33
+ if (e?.code === 'ENOENT')
34
+ return false;
35
+ throw e;
36
+ }
37
+ }
38
+ async exists(key) {
39
+ try {
40
+ await fs.stat(this.resolveKey(key));
41
+ return true;
42
+ }
43
+ catch (e) {
44
+ if (e?.code === 'ENOENT')
45
+ return false;
46
+ throw e;
47
+ }
48
+ }
49
+ getUrl(key, filename) {
50
+ const baseUrl = this.config.baseUrl ?? '/api/files';
51
+ const filePart = encodeURIComponent(key);
52
+ if (!filename)
53
+ return `${baseUrl}/${filePart}`;
54
+ return `${baseUrl}/${filePart}?filename=${encodeURIComponent(filename)}`;
55
+ }
56
+ }
57
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;IAAG,CAAC;IAEnD,UAAU,CAAC,GAAW;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,MAAc;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACtC,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC;YACvC,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,QAAiB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,YAAY,CAAC;QACpD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ;YAAE,OAAO,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/C,OAAO,GAAG,OAAO,IAAI,QAAQ,aAAa,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC3E,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export declare function requiredEnv(name: string, fallback?: string): string;
2
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,UAO1D"}
@@ -0,0 +1,10 @@
1
+ export function requiredEnv(name, fallback) {
2
+ const v = process.env[name];
3
+ if (v == null || v === '') {
4
+ if (fallback != null)
5
+ return fallback;
6
+ throw new Error(`Missing env: ${name}`);
7
+ }
8
+ return v;
9
+ }
10
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,QAAiB;IACzD,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QAC1B,IAAI,QAAQ,IAAI,IAAI;YAAE,OAAO,QAAQ,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './env.js';
2
+ export * from './logger.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './env.js';
2
+ export * from './logger.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export declare function createLogger(scope: string): {
3
+ debug: (...args: any[]) => void;
4
+ info: (...args: any[]) => void;
5
+ warn: (...args: any[]) => void;
6
+ error: (...args: any[]) => void;
7
+ };
8
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM;qBAGrB,GAAG,EAAE;oBACN,GAAG,EAAE;oBACL,GAAG,EAAE;qBACJ,GAAG,EAAE;EAEzB"}
@@ -0,0 +1,10 @@
1
+ export function createLogger(scope) {
2
+ const prefix = `[${scope}]`;
3
+ return {
4
+ debug: (...args) => console.debug(prefix, ...args),
5
+ info: (...args) => console.info(prefix, ...args),
6
+ warn: (...args) => console.warn(prefix, ...args),
7
+ error: (...args) => console.error(prefix, ...args),
8
+ };
9
+ }
10
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,MAAM,GAAG,IAAI,KAAK,GAAG,CAAC;IAC5B,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;QACzD,IAAI,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;QACvD,IAAI,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;QACvD,KAAK,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;KAC1D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { WebSocket } from 'ws';
2
+ export type ConnectionSet = Set<WebSocket>;
3
+ export declare function safeClose(ws: WebSocket, code?: number, reason?: string): void;
4
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/websocket/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;AAE3C,wBAAgB,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,QAMtE"}
@@ -0,0 +1,9 @@
1
+ export function safeClose(ws, code, reason) {
2
+ try {
3
+ ws.close(code, reason);
4
+ }
5
+ catch {
6
+ // ignore
7
+ }
8
+ }
9
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/websocket/connection.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,SAAS,CAAC,EAAa,EAAE,IAAa,EAAE,MAAe;IACrE,IAAI,CAAC;QACH,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { WebSocket } from 'ws';
2
+ export declare function startHeartbeat(clients: Iterable<WebSocket>, intervalMs?: number): () => void;
3
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/websocket/heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,SAAQ,cAa9E"}
@@ -0,0 +1,16 @@
1
+ export function startHeartbeat(clients, intervalMs = 30000) {
2
+ const timer = setInterval(() => {
3
+ for (const ws of clients) {
4
+ if (ws.readyState !== ws.OPEN)
5
+ continue;
6
+ try {
7
+ ws.ping();
8
+ }
9
+ catch {
10
+ // ignore
11
+ }
12
+ }
13
+ }, intervalMs);
14
+ return () => clearInterval(timer);
15
+ }
16
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/websocket/heartbeat.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,OAA4B,EAAE,UAAU,GAAG,KAAK;IAC7E,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACzB,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI;gBAAE,SAAS;YACxC,IAAI,CAAC;gBACH,EAAE,CAAC,IAAI,EAAE,CAAC;YACZ,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC,EAAE,UAAU,CAAC,CAAC;IAEf,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './heartbeat.js';
2
+ export * from './connection.js';
3
+ export * from './server.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './heartbeat.js';
2
+ export * from './connection.js';
3
+ export * from './server.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type http from 'node:http';
2
+ import { type WebSocket } from 'ws';
3
+ export type BasicWsServerOptions = {
4
+ path: string;
5
+ onConnection: (ws: WebSocket) => void;
6
+ };
7
+ export declare class BasicWsServer {
8
+ private wss?;
9
+ attach(server: http.Server, options: BasicWsServerOptions): void;
10
+ close(): void;
11
+ }
12
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/websocket/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,IAAI,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAC,CAAkB;IAE9B,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,oBAAoB;IAKzD,KAAK;CAGN"}
@@ -0,0 +1,12 @@
1
+ import { WebSocketServer } from 'ws';
2
+ export class BasicWsServer {
3
+ wss;
4
+ attach(server, options) {
5
+ this.wss = new WebSocketServer({ server, path: options.path });
6
+ this.wss.on('connection', options.onConnection);
7
+ }
8
+ close() {
9
+ this.wss?.close();
10
+ }
11
+ }
12
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/websocket/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AAOrD,MAAM,OAAO,aAAa;IAChB,GAAG,CAAmB;IAE9B,MAAM,CAAC,MAAmB,EAAE,OAA6B;QACvD,IAAI,CAAC,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;IACpB,CAAC;CACF"}