@kyro-cms/core 0.12.71 → 0.13.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.
- package/README.md +150 -76
- package/dist/{WebhookService-DQyM9fVo.d.ts → WebhookService-BLi5Rz2m.d.ts} +1 -1
- package/dist/{WebhookService-bo1NrgBW.d.cts → WebhookService-BOJMgjBm.d.cts} +1 -1
- package/dist/WebhookService-BcuD8tnn.d.cts +143 -0
- package/dist/WebhookService-CFe6Zd0_.d.cts +143 -0
- package/dist/WebhookService-CGxHtw7E.d.cts +143 -0
- package/dist/WebhookService-CNC1lYz7.d.ts +143 -0
- package/dist/WebhookService-CVXmjbtQ.d.cts +143 -0
- package/dist/WebhookService-D5PSI5t6.d.cts +143 -0
- package/dist/WebhookService-DPCCn_12.d.ts +143 -0
- package/dist/WebhookService-Dk1lzSrG.d.cts +143 -0
- package/dist/WebhookService-Dncnbgm9.d.cts +143 -0
- package/dist/WebhookService-I6hdue2Y.d.ts +143 -0
- package/dist/WebhookService-KnQ2UDlW.d.ts +143 -0
- package/dist/WebhookService-UY5p89Bj.d.ts +143 -0
- package/dist/WebhookService-YZXBCRXA.d.ts +143 -0
- package/dist/WebhookService-fk0FGRlk.d.ts +143 -0
- package/dist/WebhookService-vsFnWrOh.d.ts +143 -0
- package/dist/WebhookService-zrDmAx7L.d.cts +143 -0
- package/dist/api-handler-graphql.cjs +1 -1
- package/dist/api-handler-graphql.js +1 -1
- package/dist/api-handler-trpc.cjs +1 -1
- package/dist/api-handler-trpc.js +1 -1
- package/dist/api-handler.cjs +1 -1
- package/dist/api-handler.js +1 -1
- package/dist/{base-urWvrsX8.d.cts → base-B--L0lCn.d.cts} +1 -1
- package/dist/base-B-i-tjm1.d.ts +218 -0
- package/dist/base-B-siit_y.d.cts +218 -0
- package/dist/base-B8SyZI4D.d.ts +218 -0
- package/dist/base-BCgFt3Yx.d.ts +218 -0
- package/dist/base-BHRGJ40F.d.cts +218 -0
- package/dist/base-BVoDPNjJ.d.cts +218 -0
- package/dist/base-BaOJ5uWd.d.cts +218 -0
- package/dist/base-BfPaVEAE.d.cts +218 -0
- package/dist/base-BxrX5EPU.d.cts +218 -0
- package/dist/base-CAb9EYQs.d.ts +218 -0
- package/dist/base-CcZIEll-.d.ts +218 -0
- package/dist/base-CyG7aF1e.d.cts +218 -0
- package/dist/{base-BcfNgOqZ.d.ts → base-DOImeJ-F.d.ts} +1 -1
- package/dist/base-DbnwE42-.d.cts +218 -0
- package/dist/base-NyiSsD-n.d.ts +218 -0
- package/dist/base-OYfoYPYP.d.ts +218 -0
- package/dist/base-xflndGDO.d.ts +218 -0
- package/dist/bootstrap-QQ6D3OYG.js +1 -0
- package/dist/bootstrap-QVKSKXJF.cjs +1 -0
- package/dist/bootstrap-RILR44UM.cjs +1 -0
- package/dist/bootstrap-ZRRUPRUR.js +1 -0
- package/dist/chunk-262YP5XA.cjs +1 -0
- package/dist/chunk-2FSOHXOU.cjs +56 -0
- package/dist/chunk-2OS5Y4LE.cjs +1 -0
- package/dist/chunk-2PXXQKN3.cjs +3 -0
- package/dist/{chunk-K6ZW5M6S.cjs → chunk-355R4LS5.cjs} +3 -3
- package/dist/chunk-35IVNLMA.js +122 -0
- package/dist/{chunk-FSWDDVLA.js → chunk-3GXLOYM3.js} +1 -1
- package/dist/chunk-3KZXF4US.js +2 -0
- package/dist/{chunk-H7PC2ENZ.cjs → chunk-3LAWUINR.cjs} +1 -1
- package/dist/chunk-3O3AVMWM.cjs +1 -0
- package/dist/chunk-3U6MKWET.cjs +120 -0
- package/dist/chunk-4BMWWGJN.js +384 -0
- package/dist/chunk-5A7E7N4B.cjs +431 -0
- package/dist/chunk-6DD4J7LI.js +2 -0
- package/dist/chunk-6GGPY7U2.js +4 -0
- package/dist/chunk-6MNLRAKM.cjs +121 -0
- package/dist/chunk-6NBZDW53.js +133 -0
- package/dist/{chunk-2HATK4C5.js → chunk-73Y63IPP.js} +4 -4
- package/dist/chunk-7K6ZUNJM.js +4 -0
- package/dist/chunk-7NKNSRCB.cjs +448 -0
- package/dist/chunk-A3IOQOV6.js +2 -0
- package/dist/chunk-A3XVL6ED.cjs +3 -0
- package/dist/{chunk-LKQHIOPW.cjs → chunk-APDQ6ZTG.cjs} +1 -1
- package/dist/chunk-ATI2UZ7U.js +2 -0
- package/dist/chunk-B4AC23SG.js +122 -0
- package/dist/chunk-BD6XHMMM.cjs +2 -0
- package/dist/chunk-CH4TZZI5.js +449 -0
- package/dist/{chunk-26KFM3P6.js → chunk-CNHUCCQJ.js} +1 -1
- package/dist/chunk-CRP6PSCE.js +2 -0
- package/dist/chunk-DI6TCZSE.js +122 -0
- package/dist/chunk-DORUYZQV.cjs +1 -0
- package/dist/chunk-E4H3ZZ7U.js +4 -0
- package/dist/chunk-EFKEVWAD.js +4 -0
- package/dist/chunk-EI7FRSNY.js +57 -0
- package/dist/chunk-EON4XLKQ.cjs +1 -0
- package/dist/chunk-EUQAOYEO.cjs +121 -0
- package/dist/chunk-EVAUBT7H.js +57 -0
- package/dist/chunk-EYHD7HZE.cjs +1 -0
- package/dist/chunk-EYYIPA5N.js +432 -0
- package/dist/chunk-F2O4QO5N.cjs +383 -0
- package/dist/chunk-FBWLSWZ4.js +122 -0
- package/dist/chunk-FDKU7HJX.js +2 -0
- package/dist/chunk-FGN6IMPY.cjs +3 -0
- package/dist/chunk-FK2BG4HU.js +3 -0
- package/dist/chunk-GV2IB4WQ.cjs +56 -0
- package/dist/chunk-GWIZT2P5.js +57 -0
- package/dist/chunk-H3FJ54KB.cjs +121 -0
- package/dist/chunk-HY3EAWB2.js +4 -0
- package/dist/chunk-I6UJVO2P.js +57 -0
- package/dist/chunk-IQSF6XRV.js +57 -0
- package/dist/chunk-IXGDTAES.js +4 -0
- package/dist/chunk-JA44K75G.js +2 -0
- package/dist/chunk-JZ7Z6WC2.cjs +3 -0
- package/dist/chunk-K5XGP57D.cjs +19 -0
- package/dist/chunk-KEITOXIP.js +2 -0
- package/dist/chunk-LPFRMQFQ.js +121 -0
- package/dist/chunk-LYU44UNN.cjs +56 -0
- package/dist/chunk-MDLJTZLV.cjs +1 -0
- package/dist/chunk-MFNN5DYG.cjs +1 -0
- package/dist/chunk-MJAODEFC.cjs +121 -0
- package/dist/chunk-MYHNTJLR.cjs +56 -0
- package/dist/chunk-N2YHO2WI.cjs +3 -0
- package/dist/chunk-N4FXLQE3.cjs +132 -0
- package/dist/chunk-NPBXLPOP.js +3 -0
- package/dist/chunk-ON5XJEPO.cjs +3 -0
- package/dist/chunk-OT2Z4XBD.cjs +1 -0
- package/dist/chunk-PFTBTWSC.cjs +1 -0
- package/dist/chunk-PTPVFLET.js +20 -0
- package/dist/chunk-PZDLPRJF.js +4 -0
- package/dist/chunk-Q5TFO66G.cjs +1 -0
- package/dist/chunk-QUTYCUST.js +4 -0
- package/dist/chunk-REKKBAQX.cjs +56 -0
- package/dist/chunk-REQ622YC.js +3 -0
- package/dist/chunk-RTNQP6BV.js +2 -0
- package/dist/chunk-RUJW47ZJ.js +2 -0
- package/dist/chunk-RXYCFZJC.cjs +121 -0
- package/dist/chunk-RYHOWZLK.js +2 -0
- package/dist/chunk-S2MZNEBQ.cjs +1 -0
- package/dist/chunk-S73YERS2.js +57 -0
- package/dist/chunk-SBNMXQNO.cjs +2 -0
- package/dist/chunk-SMQ6736Y.js +57 -0
- package/dist/chunk-T3DJ3UTP.cjs +121 -0
- package/dist/chunk-TJZO7ZSX.cjs +3 -0
- package/dist/chunk-TKUNRCRH.js +4 -0
- package/dist/chunk-TQLCOMKC.js +4 -0
- package/dist/chunk-TRXYDWGE.cjs +1 -0
- package/dist/chunk-TS55CUNJ.js +57 -0
- package/dist/chunk-UFBJ3WOZ.js +2 -0
- package/dist/chunk-UQRVQUVR.js +2 -0
- package/dist/chunk-UW5W35NP.js +122 -0
- package/dist/chunk-VI7WCO2J.cjs +3 -0
- package/dist/chunk-W2GPP6RB.js +122 -0
- package/dist/chunk-WHOA7YJU.cjs +1 -0
- package/dist/chunk-WNRUPL26.js +2 -0
- package/dist/chunk-WXT2XW7T.js +13 -0
- package/dist/chunk-XFYSADHV.cjs +2 -0
- package/dist/chunk-XIAJQLGS.js +2 -0
- package/dist/chunk-XK6UB77Q.js +4 -0
- package/dist/chunk-Y2VHO66Q.cjs +3 -0
- package/dist/chunk-Y5O2OD7J.cjs +3 -0
- package/dist/chunk-YARB43JG.cjs +56 -0
- package/dist/chunk-YLCEMVYY.cjs +56 -0
- package/dist/chunk-YSOM57GK.cjs +3 -0
- package/dist/chunk-Z3UVDGYS.cjs +56 -0
- package/dist/chunk-ZTLGK6R4.cjs +12 -0
- package/dist/chunk-ZUBJ6RLQ.cjs +1 -0
- package/dist/cli/index.cjs +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/client.cjs +10 -10
- package/dist/client.d.cts +1265 -0
- package/dist/client.d.ts +1265 -0
- package/dist/client.js +10 -10
- package/dist/drizzle/index.cjs +1 -1
- package/dist/drizzle/index.d.cts +3 -3
- package/dist/drizzle/index.d.ts +3 -3
- package/dist/drizzle/index.js +1 -1
- package/dist/fields/index.cjs +1 -1
- package/dist/fields/index.d.cts +2 -2
- package/dist/fields/index.d.ts +2 -2
- package/dist/fields/index.js +1 -1
- package/dist/graphql/index.d.cts +3 -3
- package/dist/graphql/index.d.ts +3 -3
- package/dist/index-8Ino7vKq.d.ts +105 -0
- package/dist/{index-d1m_oup7.d.cts → index-B9BFNOHd.d.cts} +1 -1
- package/dist/index-BMcYFpTv.d.cts +105 -0
- package/dist/index-BttsFZDa.d.ts +105 -0
- package/dist/index-ByOM1Y5x.d.ts +105 -0
- package/dist/index-C6xmtRio.d.cts +105 -0
- package/dist/index-CTI3K_uq.d.cts +105 -0
- package/dist/index-CTL4zv_u.d.ts +105 -0
- package/dist/index-CaDbioSg.d.ts +105 -0
- package/dist/index-CxA9uOv0.d.ts +105 -0
- package/dist/{index-4cH-BjtP.d.ts → index-D6AXbuPI.d.ts} +1 -1
- package/dist/index-DF0KDBaM.d.cts +105 -0
- package/dist/index-DG4Xu7gA.d.cts +105 -0
- package/dist/index-DS3DpJli.d.cts +105 -0
- package/dist/index-NGnJpSgf.d.ts +105 -0
- package/dist/index-Zrg3sZ6R.d.cts +105 -0
- package/dist/index-eHex8Iwj.d.ts +105 -0
- package/dist/index-rm7uyOK1.d.cts +105 -0
- package/dist/index.cjs +32 -32
- package/dist/index.d.cts +73 -11
- package/dist/index.d.ts +73 -11
- package/dist/index.js +32 -32
- package/dist/lib-A2D63VXD.cjs +1 -0
- package/dist/lib-JQD2JAOO.js +2 -0
- package/dist/local-KR3AIGVA.cjs +1 -0
- package/dist/local-T7GISZBL.js +1 -0
- package/dist/mongo-auth-adapter-GR2CFFEA.js +1 -0
- package/dist/mongo-auth-adapter-UOO2LZUJ.cjs +1 -0
- package/dist/mongodb/index.cjs +1 -1
- package/dist/mongodb/index.d.cts +4 -3
- package/dist/mongodb/index.d.ts +4 -3
- package/dist/mongodb/index.js +1 -1
- package/dist/nodemailer-transport-3VWVUBM5.cjs +1 -0
- package/dist/nodemailer-transport-7RHATUKL.js +1 -0
- package/dist/nodemailer-transport-CHO2WKIY.js +1 -0
- package/dist/nodemailer-transport-ED2IXNGW.cjs +1 -0
- package/dist/rest/index.cjs +1 -1
- package/dist/rest/index.d.cts +4 -4
- package/dist/rest/index.d.ts +4 -4
- package/dist/rest/index.js +1 -1
- package/dist/templates/index.cjs +1 -1
- package/dist/templates/index.d.cts +2 -2
- package/dist/templates/index.d.ts +2 -2
- package/dist/templates/index.js +1 -1
- package/dist/trpc/index.cjs +1 -1
- package/dist/trpc/index.d.cts +3 -3
- package/dist/trpc/index.d.ts +3 -3
- package/dist/trpc/index.js +1 -1
- package/dist/types-6ShQp2EM.d.cts +839 -0
- package/dist/types-B5Qz1svz.d.cts +822 -0
- package/dist/types-B9oXBEKI.d.cts +330 -0
- package/dist/types-B9oXBEKI.d.ts +330 -0
- package/dist/types-BCOhfwHC.d.ts +839 -0
- package/dist/types-BRDBNacn.d.ts +839 -0
- package/dist/types-Bii0bhUV.d.cts +329 -0
- package/dist/types-Bii0bhUV.d.ts +329 -0
- package/dist/{types-BADIMVGF.d.ts → types-Bt2_ycUO.d.ts} +36 -1
- package/dist/types-C4wXHImf.d.ts +822 -0
- package/dist/types-C8yIAV6K.d.cts +839 -0
- package/dist/types-CORUQhY-.d.ts +839 -0
- package/dist/types-Cdssrcbz.d.cts +839 -0
- package/dist/types-CjGqxBd3.d.cts +330 -0
- package/dist/types-CjGqxBd3.d.ts +330 -0
- package/dist/types-DBGR-eQl.d.cts +839 -0
- package/dist/types-DCWgPFmi.d.cts +822 -0
- package/dist/types-DROqAsr0.d.cts +330 -0
- package/dist/types-DROqAsr0.d.ts +330 -0
- package/dist/{types-YAVR0H9Z.d.cts → types-DsF64Wrc.d.cts} +36 -1
- package/dist/types-DxaK39ix.d.cts +330 -0
- package/dist/types-DxaK39ix.d.ts +330 -0
- package/dist/types-IeKFn7Ky.d.ts +839 -0
- package/dist/types-QglJ7PwT.d.cts +839 -0
- package/dist/types-ZrjEVWfi.d.ts +811 -0
- package/dist/types-dEy5JxvN.d.ts +822 -0
- package/dist/types-tVJc9YbX.d.cts +811 -0
- package/dist/types-zt5qIvje.d.ts +839 -0
- package/dist/ws/index.cjs +1 -1
- package/dist/ws/index.d.cts +121 -1
- package/dist/ws/index.d.ts +121 -1
- package/dist/ws/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-5M3FKE2V.js +0 -2
- package/dist/chunk-WCFHS7EZ.cjs +0 -1
package/dist/ws/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunkMDLJTZLV_cjs=require('../chunk-MDLJTZLV.cjs');require('../chunk-73D2PNHD.cjs'),require('../chunk-BUNLC3II.cjs');Object.defineProperty(exports,"KyroPubSub",{enumerable:true,get:function(){return chunkMDLJTZLV_cjs.b}});Object.defineProperty(exports,"KyroWSServer",{enumerable:true,get:function(){return chunkMDLJTZLV_cjs.d}});Object.defineProperty(exports,"PresenceManager",{enumerable:true,get:function(){return chunkMDLJTZLV_cjs.c}});Object.defineProperty(exports,"PubSub",{enumerable:true,get:function(){return chunkMDLJTZLV_cjs.a}});Object.defineProperty(exports,"createWSServer",{enumerable:true,get:function(){return chunkMDLJTZLV_cjs.e}});
|
package/dist/ws/index.d.cts
CHANGED
|
@@ -36,6 +36,117 @@ declare class KyroPubSub extends PubSub {
|
|
|
36
36
|
autoRegisterHooks(): void;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
interface PresenceUser {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
email?: string;
|
|
43
|
+
avatar?: string;
|
|
44
|
+
color?: string;
|
|
45
|
+
lastSeen: number;
|
|
46
|
+
}
|
|
47
|
+
interface CursorState {
|
|
48
|
+
userId: string;
|
|
49
|
+
field?: string;
|
|
50
|
+
position?: number;
|
|
51
|
+
selection?: {
|
|
52
|
+
start: number;
|
|
53
|
+
end: number;
|
|
54
|
+
};
|
|
55
|
+
updatedAt: number;
|
|
56
|
+
}
|
|
57
|
+
interface FieldLock {
|
|
58
|
+
fieldName: string;
|
|
59
|
+
userId: string;
|
|
60
|
+
userName: string;
|
|
61
|
+
lockedAt: number;
|
|
62
|
+
expiresAt: number;
|
|
63
|
+
}
|
|
64
|
+
interface DocComment {
|
|
65
|
+
id: string;
|
|
66
|
+
authorId: string;
|
|
67
|
+
authorName: string;
|
|
68
|
+
field?: string;
|
|
69
|
+
text: string;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
resolved?: boolean;
|
|
72
|
+
}
|
|
73
|
+
interface DocPresenceState {
|
|
74
|
+
docKey: string;
|
|
75
|
+
users: Map<string, PresenceUser>;
|
|
76
|
+
cursors: Map<string, CursorState>;
|
|
77
|
+
locks: Map<string, FieldLock>;
|
|
78
|
+
comments: DocComment[];
|
|
79
|
+
}
|
|
80
|
+
declare class PresenceManager {
|
|
81
|
+
private documents;
|
|
82
|
+
private defaultLockTtlMs;
|
|
83
|
+
private getOrCreateDoc;
|
|
84
|
+
/**
|
|
85
|
+
* User joins a document room
|
|
86
|
+
*/
|
|
87
|
+
join(docKey: string, user: Omit<PresenceUser, 'lastSeen'>): PresenceUser[];
|
|
88
|
+
/**
|
|
89
|
+
* User leaves a document room
|
|
90
|
+
*/
|
|
91
|
+
leave(docKey: string, userId: string): {
|
|
92
|
+
remainingUsers: PresenceUser[];
|
|
93
|
+
releasedLocks: string[];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Updates user cursor / focused field in real time
|
|
97
|
+
*/
|
|
98
|
+
updateCursor(docKey: string, userId: string, cursor: {
|
|
99
|
+
field?: string;
|
|
100
|
+
position?: number;
|
|
101
|
+
selection?: {
|
|
102
|
+
start: number;
|
|
103
|
+
end: number;
|
|
104
|
+
};
|
|
105
|
+
}): CursorState;
|
|
106
|
+
/**
|
|
107
|
+
* Attempts to acquire an exclusive lock on a field
|
|
108
|
+
*/
|
|
109
|
+
acquireLock(docKey: string, fieldName: string, user: {
|
|
110
|
+
id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
}, ttlMs?: number): {
|
|
113
|
+
success: boolean;
|
|
114
|
+
lock?: FieldLock;
|
|
115
|
+
currentLock?: FieldLock;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Releases an exclusive lock on a field
|
|
119
|
+
*/
|
|
120
|
+
releaseLock(docKey: string, fieldName: string, userId: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Adds an editorial review comment
|
|
123
|
+
*/
|
|
124
|
+
addComment(docKey: string, comment: {
|
|
125
|
+
id: string;
|
|
126
|
+
authorId: string;
|
|
127
|
+
authorName: string;
|
|
128
|
+
field?: string;
|
|
129
|
+
text: string;
|
|
130
|
+
}): DocComment;
|
|
131
|
+
/**
|
|
132
|
+
* Resolves an editorial comment
|
|
133
|
+
*/
|
|
134
|
+
resolveComment(docKey: string, commentId: string): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Returns snapshot of entire presence state for a document
|
|
137
|
+
*/
|
|
138
|
+
getSnapshot(docKey: string): {
|
|
139
|
+
users: PresenceUser[];
|
|
140
|
+
cursors: CursorState[];
|
|
141
|
+
locks: FieldLock[];
|
|
142
|
+
comments: DocComment[];
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Deterministic avatar color generator for users
|
|
146
|
+
*/
|
|
147
|
+
private generateUserColor;
|
|
148
|
+
}
|
|
149
|
+
|
|
39
150
|
interface WSServerOptions {
|
|
40
151
|
port?: number;
|
|
41
152
|
pubsub: KyroPubSub;
|
|
@@ -57,6 +168,7 @@ interface WSClient {
|
|
|
57
168
|
tenantId?: string;
|
|
58
169
|
connectedAt: Date;
|
|
59
170
|
lastActivity: Date;
|
|
171
|
+
activeDocKey?: string;
|
|
60
172
|
}
|
|
61
173
|
declare class KyroWSServer {
|
|
62
174
|
private wss;
|
|
@@ -64,6 +176,7 @@ declare class KyroWSServer {
|
|
|
64
176
|
private pubsub;
|
|
65
177
|
private options;
|
|
66
178
|
private pingTimer?;
|
|
179
|
+
readonly presence: PresenceManager;
|
|
67
180
|
constructor(options: WSServerOptions);
|
|
68
181
|
private setupServer;
|
|
69
182
|
private handleMessage;
|
|
@@ -72,6 +185,13 @@ declare class KyroWSServer {
|
|
|
72
185
|
private handleUnsubscribe;
|
|
73
186
|
private handleUnsubscribeAll;
|
|
74
187
|
private handleList;
|
|
188
|
+
private handlePresenceJoin;
|
|
189
|
+
private handlePresenceLeave;
|
|
190
|
+
private handlePresenceCursor;
|
|
191
|
+
private handlePresenceLock;
|
|
192
|
+
private handlePresenceUnlock;
|
|
193
|
+
private handlePresenceComment;
|
|
194
|
+
private handlePresenceSnapshot;
|
|
75
195
|
private handleDisconnect;
|
|
76
196
|
private sendToClient;
|
|
77
197
|
private generateClientId;
|
|
@@ -85,4 +205,4 @@ declare class KyroWSServer {
|
|
|
85
205
|
}
|
|
86
206
|
declare function createWSServer(options: WSServerOptions): KyroWSServer;
|
|
87
207
|
|
|
88
|
-
export { type EventHandler, type KyroEvent, KyroPubSub, KyroWSServer, PubSub, type WSClient, type WSServerOptions, createWSServer };
|
|
208
|
+
export { type CursorState, type DocComment, type DocPresenceState, type EventHandler, type FieldLock, type KyroEvent, KyroPubSub, KyroWSServer, PresenceManager, type PresenceUser, PubSub, type WSClient, type WSServerOptions, createWSServer };
|
package/dist/ws/index.d.ts
CHANGED
|
@@ -36,6 +36,117 @@ declare class KyroPubSub extends PubSub {
|
|
|
36
36
|
autoRegisterHooks(): void;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
interface PresenceUser {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
email?: string;
|
|
43
|
+
avatar?: string;
|
|
44
|
+
color?: string;
|
|
45
|
+
lastSeen: number;
|
|
46
|
+
}
|
|
47
|
+
interface CursorState {
|
|
48
|
+
userId: string;
|
|
49
|
+
field?: string;
|
|
50
|
+
position?: number;
|
|
51
|
+
selection?: {
|
|
52
|
+
start: number;
|
|
53
|
+
end: number;
|
|
54
|
+
};
|
|
55
|
+
updatedAt: number;
|
|
56
|
+
}
|
|
57
|
+
interface FieldLock {
|
|
58
|
+
fieldName: string;
|
|
59
|
+
userId: string;
|
|
60
|
+
userName: string;
|
|
61
|
+
lockedAt: number;
|
|
62
|
+
expiresAt: number;
|
|
63
|
+
}
|
|
64
|
+
interface DocComment {
|
|
65
|
+
id: string;
|
|
66
|
+
authorId: string;
|
|
67
|
+
authorName: string;
|
|
68
|
+
field?: string;
|
|
69
|
+
text: string;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
resolved?: boolean;
|
|
72
|
+
}
|
|
73
|
+
interface DocPresenceState {
|
|
74
|
+
docKey: string;
|
|
75
|
+
users: Map<string, PresenceUser>;
|
|
76
|
+
cursors: Map<string, CursorState>;
|
|
77
|
+
locks: Map<string, FieldLock>;
|
|
78
|
+
comments: DocComment[];
|
|
79
|
+
}
|
|
80
|
+
declare class PresenceManager {
|
|
81
|
+
private documents;
|
|
82
|
+
private defaultLockTtlMs;
|
|
83
|
+
private getOrCreateDoc;
|
|
84
|
+
/**
|
|
85
|
+
* User joins a document room
|
|
86
|
+
*/
|
|
87
|
+
join(docKey: string, user: Omit<PresenceUser, 'lastSeen'>): PresenceUser[];
|
|
88
|
+
/**
|
|
89
|
+
* User leaves a document room
|
|
90
|
+
*/
|
|
91
|
+
leave(docKey: string, userId: string): {
|
|
92
|
+
remainingUsers: PresenceUser[];
|
|
93
|
+
releasedLocks: string[];
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Updates user cursor / focused field in real time
|
|
97
|
+
*/
|
|
98
|
+
updateCursor(docKey: string, userId: string, cursor: {
|
|
99
|
+
field?: string;
|
|
100
|
+
position?: number;
|
|
101
|
+
selection?: {
|
|
102
|
+
start: number;
|
|
103
|
+
end: number;
|
|
104
|
+
};
|
|
105
|
+
}): CursorState;
|
|
106
|
+
/**
|
|
107
|
+
* Attempts to acquire an exclusive lock on a field
|
|
108
|
+
*/
|
|
109
|
+
acquireLock(docKey: string, fieldName: string, user: {
|
|
110
|
+
id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
}, ttlMs?: number): {
|
|
113
|
+
success: boolean;
|
|
114
|
+
lock?: FieldLock;
|
|
115
|
+
currentLock?: FieldLock;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Releases an exclusive lock on a field
|
|
119
|
+
*/
|
|
120
|
+
releaseLock(docKey: string, fieldName: string, userId: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Adds an editorial review comment
|
|
123
|
+
*/
|
|
124
|
+
addComment(docKey: string, comment: {
|
|
125
|
+
id: string;
|
|
126
|
+
authorId: string;
|
|
127
|
+
authorName: string;
|
|
128
|
+
field?: string;
|
|
129
|
+
text: string;
|
|
130
|
+
}): DocComment;
|
|
131
|
+
/**
|
|
132
|
+
* Resolves an editorial comment
|
|
133
|
+
*/
|
|
134
|
+
resolveComment(docKey: string, commentId: string): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Returns snapshot of entire presence state for a document
|
|
137
|
+
*/
|
|
138
|
+
getSnapshot(docKey: string): {
|
|
139
|
+
users: PresenceUser[];
|
|
140
|
+
cursors: CursorState[];
|
|
141
|
+
locks: FieldLock[];
|
|
142
|
+
comments: DocComment[];
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Deterministic avatar color generator for users
|
|
146
|
+
*/
|
|
147
|
+
private generateUserColor;
|
|
148
|
+
}
|
|
149
|
+
|
|
39
150
|
interface WSServerOptions {
|
|
40
151
|
port?: number;
|
|
41
152
|
pubsub: KyroPubSub;
|
|
@@ -57,6 +168,7 @@ interface WSClient {
|
|
|
57
168
|
tenantId?: string;
|
|
58
169
|
connectedAt: Date;
|
|
59
170
|
lastActivity: Date;
|
|
171
|
+
activeDocKey?: string;
|
|
60
172
|
}
|
|
61
173
|
declare class KyroWSServer {
|
|
62
174
|
private wss;
|
|
@@ -64,6 +176,7 @@ declare class KyroWSServer {
|
|
|
64
176
|
private pubsub;
|
|
65
177
|
private options;
|
|
66
178
|
private pingTimer?;
|
|
179
|
+
readonly presence: PresenceManager;
|
|
67
180
|
constructor(options: WSServerOptions);
|
|
68
181
|
private setupServer;
|
|
69
182
|
private handleMessage;
|
|
@@ -72,6 +185,13 @@ declare class KyroWSServer {
|
|
|
72
185
|
private handleUnsubscribe;
|
|
73
186
|
private handleUnsubscribeAll;
|
|
74
187
|
private handleList;
|
|
188
|
+
private handlePresenceJoin;
|
|
189
|
+
private handlePresenceLeave;
|
|
190
|
+
private handlePresenceCursor;
|
|
191
|
+
private handlePresenceLock;
|
|
192
|
+
private handlePresenceUnlock;
|
|
193
|
+
private handlePresenceComment;
|
|
194
|
+
private handlePresenceSnapshot;
|
|
75
195
|
private handleDisconnect;
|
|
76
196
|
private sendToClient;
|
|
77
197
|
private generateClientId;
|
|
@@ -85,4 +205,4 @@ declare class KyroWSServer {
|
|
|
85
205
|
}
|
|
86
206
|
declare function createWSServer(options: WSServerOptions): KyroWSServer;
|
|
87
207
|
|
|
88
|
-
export { type EventHandler, type KyroEvent, KyroPubSub, KyroWSServer, PubSub, type WSClient, type WSServerOptions, createWSServer };
|
|
208
|
+
export { type CursorState, type DocComment, type DocPresenceState, type EventHandler, type FieldLock, type KyroEvent, KyroPubSub, KyroWSServer, PresenceManager, type PresenceUser, PubSub, type WSClient, type WSServerOptions, createWSServer };
|
package/dist/ws/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{b as KyroPubSub,
|
|
1
|
+
export{b as KyroPubSub,d as KyroWSServer,c as PresenceManager,a as PubSub,e as createWSServer}from'../chunk-KEITOXIP.js';import'../chunk-7MNDQU6K.js';import'../chunk-Y2YAKDEQ.js';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kyro-cms/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Astro-native headless CMS with multi-database adapters, multi-protocol APIs, and multi-vendor support",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
"ws": "^8.18.0",
|
|
192
192
|
"zod": "^3.24.0",
|
|
193
193
|
"zod-to-json-schema": "^3.25.2",
|
|
194
|
-
"@kyro-cms/ai": "0.
|
|
194
|
+
"@kyro-cms/ai": "0.13.0"
|
|
195
195
|
},
|
|
196
196
|
"devDependencies": {
|
|
197
197
|
"@tailwindcss/vite": "^4.0.0",
|
package/dist/chunk-5M3FKE2V.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import {b,a as a$1}from'./chunk-7MNDQU6K.js';import {g}from'./chunk-Y2YAKDEQ.js';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
|
|
2
|
-
g();g();var a=class{channels=new Map;maxListeners;constructor(e=100){this.maxListeners=e;}subscribe(e,t){this.channels.has(e)||this.channels.set(e,new Set);let s=this.channels.get(e);if(s.size>=this.maxListeners)throw new Error(`Max listeners (${this.maxListeners}) reached for channel "${e}"`);return s.add(t),()=>{s.delete(t),s.size===0&&this.channels.delete(e);}}publish(e,t){let s=this.channels.get(e);if(s)for(let n of s)try{let i=n(t);i instanceof Promise&&i.catch(b=>{console.error(`[PubSub] Error in handler for channel "${e}":`,b);});}catch(i){console.error(`[PubSub] Error in handler for channel "${e}":`,i);}}hasSubscribers(e){return this.channels.has(e)&&this.channels.get(e).size>0}getSubscriberCount(e){return this.channels.get(e)?.size||0}getChannels(){return Array.from(this.channels.keys())}clear(){this.channels.clear();}},l=class extends a{registry;constructor(e,t=100){super(t),this.registry=e;}publishCollectionEvent(e,t){this.publish(`collection:${e}`,t),this.publish("events:collection",t),t.tenantId&&(this.publish(`tenant:${t.tenantId}:collection:${e}`,t),this.publish(`tenant:${t.tenantId}:events`,t)),this.publish(`collection:${e}:${t.type}`,t);}subscribeToCollection(e,t){return this.subscribe(`collection:${e}`,t)}subscribeToCollectionEvent(e,t,s){return this.subscribe(`collection:${e}:${t}`,s)}subscribeToTenant(e,t){return this.subscribe(`tenant:${e}:events`,t)}subscribeToTenantCollection(e,t,s){return this.subscribe(`tenant:${e}:collection:${t}`,s)}subscribeToAllCollections(e){return this.subscribe("events:collection",e)}createAfterChangeHook(e){return async t=>{this.publishCollectionEvent(e,{type:t.operation==="create"?"create":"update",collection:e,doc:t.doc,originalDoc:t.originalDoc,id:t.id||t.doc?.id,tenantId:t.tenantId,timestamp:new Date().toISOString(),user:t.user});}}createAfterDeleteHook(e){return async t=>{this.publishCollectionEvent(e,{type:"delete",collection:e,doc:t.doc,originalDoc:t.originalDoc,id:t.id||t.doc?.id,tenantId:t.tenantId,timestamp:new Date().toISOString(),user:t.user});}}autoRegisterHooks(){let e=this.registry.getCollections();for(let t of e){let s=this.registry.getCollection(t.slug);s&&(s.hooks||(s.hooks={}),s.hooks.afterChange||(s.hooks.afterChange=[]),s.hooks.afterDelete||(s.hooks.afterDelete=[]),s.hooks.afterChange.push(this.createAfterChangeHook(t.slug)),s.hooks.afterDelete.push(this.createAfterDeleteHook(t.slug)));}}};g();var c=class{wss;clients=new Map;pubsub;options;pingTimer;constructor(e){this.options=e,this.pubsub=e.pubsub,this.wss=new b.default({port:e.port||8080}),this.setupServer(),this.startPingInterval();}setupServer(){this.wss.on("connection",(e,t)=>{let s=this.generateClientId();if(this.options.maxConnections&&this.clients.size>=this.options.maxConnections){e.close(1013,"Server at capacity");return}let n={id:s,ws:e,subscriptions:new Map,authenticated:false,connectedAt:new Date,lastActivity:new Date};this.clients.set(s,n),this.sendToClient(n,{type:"connected",clientId:s,timestamp:new Date().toISOString()}),e.on("message",i=>{this.handleMessage(n,i);}),e.on("error",i=>{console.error(`[WS] Client error ${s}:`,i);}),e.on("close",()=>{this.handleDisconnect(n);}),e.on("pong",()=>{n.lastActivity=new Date;});}),this.wss.on("error",e=>{console.error("[WS] Server error:",e);});}handleMessage(e,t){e.lastActivity=new Date;let s;try{s=JSON.parse(t.toString());}catch{this.sendToClient(e,{type:"error",error:"Invalid JSON"});return}switch(s.type){case "authenticate":this.handleAuthenticate(e,s);break;case "subscribe":this.handleSubscribe(e,s);break;case "unsubscribe":this.handleUnsubscribe(e,s);break;case "unsubscribeAll":this.handleUnsubscribeAll(e);break;case "list":this.handleList(e);break;case "ping":this.sendToClient(e,{type:"pong",timestamp:new Date().toISOString()});break;default:this.sendToClient(e,{type:"error",error:`Unknown message type: ${s.type}`});}}async handleAuthenticate(e,t){if(!this.options.requireAuth){e.authenticated=true,this.sendToClient(e,{type:"authenticated",success:true});return}if(!this.options.verifyToken){e.authenticated=true,this.sendToClient(e,{type:"authenticated",success:true});return}try{let s=await this.options.verifyToken(t.token);e.authenticated=!0,e.user=s,e.tenantId=s.tenantId,this.sendToClient(e,{type:"authenticated",success:!0,user:{id:s.id,email:s.email}});}catch(s){this.sendToClient(e,{type:"authenticated",success:false,error:s.message});}}handleSubscribe(e,t){if(this.options.requireAuth&&!e.authenticated){this.sendToClient(e,{type:"error",error:"Not authenticated"});return}let s=t.channel;if(!s){this.sendToClient(e,{type:"error",error:"Channel is required"});return}if(e.subscriptions.has(s)){this.sendToClient(e,{type:"subscribed",channel:s,success:true,message:"Already subscribed"});return}let n=this.pubsub.subscribe(s,i=>{this.sendToClient(e,{type:"event",channel:s,data:i,timestamp:new Date().toISOString()});});e.subscriptions.set(s,{channel:s,unsubscribe:n}),this.sendToClient(e,{type:"subscribed",channel:s,success:true});}handleUnsubscribe(e,t){let s=t.channel;if(!s){this.sendToClient(e,{type:"error",error:"Channel is required"});return}let n=e.subscriptions.get(s);n?(n.unsubscribe(),e.subscriptions.delete(s),this.sendToClient(e,{type:"unsubscribed",channel:s,success:true})):this.sendToClient(e,{type:"unsubscribed",channel:s,success:false,message:"Not subscribed"});}handleUnsubscribeAll(e){for(let[,t]of e.subscriptions)t.unsubscribe();e.subscriptions.clear(),this.sendToClient(e,{type:"unsubscribedAll",success:true});}handleList(e){let t=this.pubsub.getChannels();this.sendToClient(e,{type:"channels",channels:t,count:t.length});}handleDisconnect(e){for(let[,t]of e.subscriptions)t.unsubscribe();this.clients.delete(e.id);}sendToClient(e,t){e.ws.readyState===a$1.default.OPEN&&e.ws.send(JSON.stringify(t));}generateClientId(){return `ws_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}startPingInterval(){this.options.pingInterval&&(this.pingTimer=setInterval(()=>{for(let[e,t]of this.clients)if(t.ws.readyState===a$1.default.OPEN){if(Date.now()-t.lastActivity.getTime()>this.options.pingInterval*3){t.ws.terminate(),this.handleDisconnect(t);continue}t.ws.ping();}},this.options.pingInterval));}broadcast(e,t){this.pubsub.publish(e,t);}getConnectedClients(){return Array.from(this.clients.values())}getClientCount(){return this.clients.size}getSubscriptionCount(){let e=0;for(let t of this.clients.values())e+=t.subscriptions.size;return e}async close(){this.pingTimer&&clearInterval(this.pingTimer);for(let e of this.clients.values())e.ws.close(1001,"Server shutting down");return new Promise(e=>{this.wss.close(()=>{e();});})}getServer(){return this.wss}};function v(o){return new c(o)}export{a,l as b,c,v as d};
|
package/dist/chunk-WCFHS7EZ.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
'use strict';var chunk73D2PNHD_cjs=require('./chunk-73D2PNHD.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs');chunkBUNLC3II_cjs.h();chunkBUNLC3II_cjs.h();var a=class{channels=new Map;maxListeners;constructor(e=100){this.maxListeners=e;}subscribe(e,t){this.channels.has(e)||this.channels.set(e,new Set);let s=this.channels.get(e);if(s.size>=this.maxListeners)throw new Error(`Max listeners (${this.maxListeners}) reached for channel "${e}"`);return s.add(t),()=>{s.delete(t),s.size===0&&this.channels.delete(e);}}publish(e,t){let s=this.channels.get(e);if(s)for(let n of s)try{let i=n(t);i instanceof Promise&&i.catch(p=>{console.error(`[PubSub] Error in handler for channel "${e}":`,p);});}catch(i){console.error(`[PubSub] Error in handler for channel "${e}":`,i);}}hasSubscribers(e){return this.channels.has(e)&&this.channels.get(e).size>0}getSubscriberCount(e){return this.channels.get(e)?.size||0}getChannels(){return Array.from(this.channels.keys())}clear(){this.channels.clear();}},l=class extends a{registry;constructor(e,t=100){super(t),this.registry=e;}publishCollectionEvent(e,t){this.publish(`collection:${e}`,t),this.publish("events:collection",t),t.tenantId&&(this.publish(`tenant:${t.tenantId}:collection:${e}`,t),this.publish(`tenant:${t.tenantId}:events`,t)),this.publish(`collection:${e}:${t.type}`,t);}subscribeToCollection(e,t){return this.subscribe(`collection:${e}`,t)}subscribeToCollectionEvent(e,t,s){return this.subscribe(`collection:${e}:${t}`,s)}subscribeToTenant(e,t){return this.subscribe(`tenant:${e}:events`,t)}subscribeToTenantCollection(e,t,s){return this.subscribe(`tenant:${e}:collection:${t}`,s)}subscribeToAllCollections(e){return this.subscribe("events:collection",e)}createAfterChangeHook(e){return async t=>{this.publishCollectionEvent(e,{type:t.operation==="create"?"create":"update",collection:e,doc:t.doc,originalDoc:t.originalDoc,id:t.id||t.doc?.id,tenantId:t.tenantId,timestamp:new Date().toISOString(),user:t.user});}}createAfterDeleteHook(e){return async t=>{this.publishCollectionEvent(e,{type:"delete",collection:e,doc:t.doc,originalDoc:t.originalDoc,id:t.id||t.doc?.id,tenantId:t.tenantId,timestamp:new Date().toISOString(),user:t.user});}}autoRegisterHooks(){let e=this.registry.getCollections();for(let t of e){let s=this.registry.getCollection(t.slug);s&&(s.hooks||(s.hooks={}),s.hooks.afterChange||(s.hooks.afterChange=[]),s.hooks.afterDelete||(s.hooks.afterDelete=[]),s.hooks.afterChange.push(this.createAfterChangeHook(t.slug)),s.hooks.afterDelete.push(this.createAfterDeleteHook(t.slug)));}}};chunkBUNLC3II_cjs.h();var c=class{wss;clients=new Map;pubsub;options;pingTimer;constructor(e){this.options=e,this.pubsub=e.pubsub,this.wss=new chunk73D2PNHD_cjs.b.default({port:e.port||8080}),this.setupServer(),this.startPingInterval();}setupServer(){this.wss.on("connection",(e,t)=>{let s=this.generateClientId();if(this.options.maxConnections&&this.clients.size>=this.options.maxConnections){e.close(1013,"Server at capacity");return}let n={id:s,ws:e,subscriptions:new Map,authenticated:false,connectedAt:new Date,lastActivity:new Date};this.clients.set(s,n),this.sendToClient(n,{type:"connected",clientId:s,timestamp:new Date().toISOString()}),e.on("message",i=>{this.handleMessage(n,i);}),e.on("error",i=>{console.error(`[WS] Client error ${s}:`,i);}),e.on("close",()=>{this.handleDisconnect(n);}),e.on("pong",()=>{n.lastActivity=new Date;});}),this.wss.on("error",e=>{console.error("[WS] Server error:",e);});}handleMessage(e,t){e.lastActivity=new Date;let s;try{s=JSON.parse(t.toString());}catch{this.sendToClient(e,{type:"error",error:"Invalid JSON"});return}switch(s.type){case "authenticate":this.handleAuthenticate(e,s);break;case "subscribe":this.handleSubscribe(e,s);break;case "unsubscribe":this.handleUnsubscribe(e,s);break;case "unsubscribeAll":this.handleUnsubscribeAll(e);break;case "list":this.handleList(e);break;case "ping":this.sendToClient(e,{type:"pong",timestamp:new Date().toISOString()});break;default:this.sendToClient(e,{type:"error",error:`Unknown message type: ${s.type}`});}}async handleAuthenticate(e,t){if(!this.options.requireAuth){e.authenticated=true,this.sendToClient(e,{type:"authenticated",success:true});return}if(!this.options.verifyToken){e.authenticated=true,this.sendToClient(e,{type:"authenticated",success:true});return}try{let s=await this.options.verifyToken(t.token);e.authenticated=!0,e.user=s,e.tenantId=s.tenantId,this.sendToClient(e,{type:"authenticated",success:!0,user:{id:s.id,email:s.email}});}catch(s){this.sendToClient(e,{type:"authenticated",success:false,error:s.message});}}handleSubscribe(e,t){if(this.options.requireAuth&&!e.authenticated){this.sendToClient(e,{type:"error",error:"Not authenticated"});return}let s=t.channel;if(!s){this.sendToClient(e,{type:"error",error:"Channel is required"});return}if(e.subscriptions.has(s)){this.sendToClient(e,{type:"subscribed",channel:s,success:true,message:"Already subscribed"});return}let n=this.pubsub.subscribe(s,i=>{this.sendToClient(e,{type:"event",channel:s,data:i,timestamp:new Date().toISOString()});});e.subscriptions.set(s,{channel:s,unsubscribe:n}),this.sendToClient(e,{type:"subscribed",channel:s,success:true});}handleUnsubscribe(e,t){let s=t.channel;if(!s){this.sendToClient(e,{type:"error",error:"Channel is required"});return}let n=e.subscriptions.get(s);n?(n.unsubscribe(),e.subscriptions.delete(s),this.sendToClient(e,{type:"unsubscribed",channel:s,success:true})):this.sendToClient(e,{type:"unsubscribed",channel:s,success:false,message:"Not subscribed"});}handleUnsubscribeAll(e){for(let[,t]of e.subscriptions)t.unsubscribe();e.subscriptions.clear(),this.sendToClient(e,{type:"unsubscribedAll",success:true});}handleList(e){let t=this.pubsub.getChannels();this.sendToClient(e,{type:"channels",channels:t,count:t.length});}handleDisconnect(e){for(let[,t]of e.subscriptions)t.unsubscribe();this.clients.delete(e.id);}sendToClient(e,t){e.ws.readyState===chunk73D2PNHD_cjs.a.default.OPEN&&e.ws.send(JSON.stringify(t));}generateClientId(){return `ws_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}startPingInterval(){this.options.pingInterval&&(this.pingTimer=setInterval(()=>{for(let[e,t]of this.clients)if(t.ws.readyState===chunk73D2PNHD_cjs.a.default.OPEN){if(Date.now()-t.lastActivity.getTime()>this.options.pingInterval*3){t.ws.terminate(),this.handleDisconnect(t);continue}t.ws.ping();}},this.options.pingInterval));}broadcast(e,t){this.pubsub.publish(e,t);}getConnectedClients(){return Array.from(this.clients.values())}getClientCount(){return this.clients.size}getSubscriptionCount(){let e=0;for(let t of this.clients.values())e+=t.subscriptions.size;return e}async close(){this.pingTimer&&clearInterval(this.pingTimer);for(let e of this.clients.values())e.ws.close(1001,"Server shutting down");return new Promise(e=>{this.wss.close(()=>{e();});})}getServer(){return this.wss}};function b(o){return new c(o)}exports.a=a;exports.b=l;exports.c=c;exports.d=b;
|