@uploadista/event-emitter-websocket 0.0.7 → 0.0.9

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/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`@uploadista/core/errors`);c=s(c);let l=require(`@uploadista/core/types`);l=s(l);let u=require(`effect`);u=s(u);const d=u.Effect.gen(function*(){let e=yield*l.EventBroadcasterService,t=new Map,n=new Map,r=(e,r)=>{let i=n.get(e);if(i)for(let e of i){let n=t.get(e);if(n&&n.readyState===1)try{n.send(r)}catch(t){console.warn(`Failed to send message to connection ${e}:`,t),s(e)}else s(e)}};yield*e.subscribe(`uploadista:events`,e=>{try{let{eventKey:t,message:n}=JSON.parse(e);r(t,n)}catch(e){console.warn(`Failed to parse broadcast message:`,e)}}).pipe(u.Effect.catchAll(e=>(console.error(`Failed to subscribe to broadcast events:`,e),u.Effect.void)));let i=e=>t.get(e)||null,a=()=>t,o=(e,n)=>{t.set(e,n)},s=e=>{t.delete(e);for(let[t,r]of n.entries())r.delete(e),r.size===0&&n.delete(t)};return{getConnection:i,getConnections:a,addConnection:o,removeConnection:s,subscribeToEvents:(e,t)=>{n.has(e)||n.set(e,new Set),n.get(e)?.add(t)},unsubscribeFromEvents:(e,t)=>{let r=n.get(e);r&&(r.delete(t),r.size===0&&n.delete(e))},emitToEvents:(t,n)=>{u.Effect.runPromise(e.publish(`uploadista:events`,JSON.stringify({eventKey:t,message:n}))).catch(e=>{console.error(`Failed to publish event to broadcaster:`,e)})}}});var f=class extends u.Context.Tag(`BaseWebSocketManagerService`)(){};const p=u.Layer.effect(f,d);function m(e){return{emit:(t,n)=>u.Effect.try({try:()=>{e.emitToEvents(t,n)},catch:e=>c.UploadistaError.fromCode(`UNKNOWN_ERROR`,{cause:e})}),subscribe:(t,n)=>u.Effect.try({try:()=>{e.addConnection(n.id,n),e.subscribeToEvents(t,n.id),n.send(JSON.stringify({type:`subscribed`,payload:{eventKey:t},timestamp:new Date().toISOString()}))},catch:e=>c.UploadistaError.fromCode(`UNKNOWN_ERROR`,{cause:e})}),unsubscribe:t=>u.Effect.try({try:()=>{let n=e.getConnections();for(let[r]of n)e.unsubscribeFromEvents(t,r)},catch:e=>c.UploadistaError.fromCode(`UNKNOWN_ERROR`,{cause:e})})}}const h=u.Effect.gen(function*(){return m(yield*f)}),g=e=>u.Layer.effect(l.BaseEventEmitterService,h).pipe(u.Layer.provide(p),u.Layer.provide(e));exports.WebSocketManagerService=f,exports.makeBaseEventEmitter=h,exports.makeWebSocketManager=d,exports.webSocketEventEmitter=g,exports.webSocketManager=p;
1
+ let e=require(`@uploadista/core/errors`),t=require(`@uploadista/core/types`),n=require(`effect`);const r=n.Effect.gen(function*(){let e=yield*t.EventBroadcasterService,r=new Map,i=new Map,a=(e,t)=>{let n=i.get(e);if(n)for(let e of n){let n=r.get(e);if(n&&n.readyState===1)try{n.send(t)}catch(t){console.warn(`Failed to send message to connection ${e}:`,t),l(e)}else l(e)}};yield*e.subscribe(`uploadista:events`,e=>{try{let{eventKey:t,message:n}=JSON.parse(e);a(t,n)}catch(e){console.warn(`Failed to parse broadcast message:`,e)}}).pipe(n.Effect.catchAll(e=>(console.error(`Failed to subscribe to broadcast events:`,e),n.Effect.void)));let o=e=>r.get(e)||null,s=()=>r,c=(e,t)=>{r.set(e,t)},l=e=>{r.delete(e);for(let[t,n]of i.entries())n.delete(e),n.size===0&&i.delete(t)};return{getConnection:o,getConnections:s,addConnection:c,removeConnection:l,subscribeToEvents:(e,t)=>{i.has(e)||i.set(e,new Set),i.get(e)?.add(t)},unsubscribeFromEvents:(e,t)=>{let n=i.get(e);n&&(n.delete(t),n.size===0&&i.delete(e))},emitToEvents:(t,r)=>{n.Effect.runPromise(e.publish(`uploadista:events`,JSON.stringify({eventKey:t,message:r}))).catch(e=>{console.error(`Failed to publish event to broadcaster:`,e)})}}});var i=class extends n.Context.Tag(`BaseWebSocketManagerService`)(){};const a=n.Layer.effect(i,r);function o(t){return{emit:(r,i)=>n.Effect.try({try:()=>{t.emitToEvents(r,i)},catch:t=>e.UploadistaError.fromCode(`UNKNOWN_ERROR`,{cause:t})}),subscribe:(r,i)=>n.Effect.try({try:()=>{t.addConnection(i.id,i),t.subscribeToEvents(r,i.id),i.send(JSON.stringify({type:`subscribed`,payload:{eventKey:r},timestamp:new Date().toISOString()}))},catch:t=>e.UploadistaError.fromCode(`UNKNOWN_ERROR`,{cause:t})}),unsubscribe:r=>n.Effect.try({try:()=>{let e=t.getConnections();for(let[n]of e)t.unsubscribeFromEvents(r,n)},catch:t=>e.UploadistaError.fromCode(`UNKNOWN_ERROR`,{cause:t})})}}const s=n.Effect.gen(function*(){return o(yield*i)}),c=e=>n.Layer.effect(t.BaseEventEmitterService,s).pipe(n.Layer.provide(a),n.Layer.provide(e));exports.WebSocketManagerService=i,exports.makeBaseEventEmitter=s,exports.makeWebSocketManager=r,exports.webSocketEventEmitter=c,exports.webSocketManager=a;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { BaseEventEmitter, BaseEventEmitterService, EventBroadcasterService, WebSocketConnection } from "@uploadista/core/types";
1
+ import { BaseEventEmitter, EventBroadcasterService, WebSocketConnection } from "@uploadista/core/types";
2
2
  import { Context, Effect, Layer } from "effect";
3
3
 
4
4
  //#region src/websocket-manager.d.ts
@@ -19,14 +19,14 @@ declare const makeWebSocketManager: Effect.Effect<{
19
19
  subscribeToEvents: (eventKey: string, connectionId: string) => void;
20
20
  unsubscribeFromEvents: (eventKey: string, connectionId: string) => void;
21
21
  emitToEvents: (eventKey: string, message: string) => void;
22
- }, never, EventBroadcasterService>;
22
+ }, unknown, unknown>;
23
23
  declare const WebSocketManagerService_base: Context.TagClass<WebSocketManagerService, "BaseWebSocketManagerService", WebSocketManager>;
24
24
  declare class WebSocketManagerService extends WebSocketManagerService_base {}
25
- declare const webSocketManager: Layer.Layer<WebSocketManagerService, never, EventBroadcasterService>;
25
+ declare const webSocketManager: Layer.Layer<WebSocketManagerService, unknown, unknown>;
26
26
  //#endregion
27
27
  //#region src/websocket-event-emitter.d.ts
28
28
  declare const makeBaseEventEmitter: Effect.Effect<BaseEventEmitter, never, WebSocketManagerService>;
29
- declare const webSocketEventEmitter: (eventBroadcaster: Layer.Layer<EventBroadcasterService>) => Layer.Layer<BaseEventEmitterService, never, never>;
29
+ declare const webSocketEventEmitter: (eventBroadcaster: Layer.Layer<EventBroadcasterService>) => Layer.Layer<unknown, unknown, never>;
30
30
  //#endregion
31
31
  export { type WebSocketManager, WebSocketManagerService, makeBaseEventEmitter, makeWebSocketManager, webSocketEventEmitter, webSocketManager };
32
32
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/websocket-manager.ts","../src/websocket-event-emitter.ts"],"sourcesContent":[],"mappings":";;;;UAKiB,gBAAA;EAAA,SAAA,aAAgB,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GACU,mBADV,GAAA,IAAA;EACU,SAAA,cAAA,EAAA,GAAA,GACV,GADU,CAAA,MAAA,EACE,mBADF,CAAA;EACE,SAAA,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,UAAA,EAG7B,mBAH6B,EAAA,GAAA,IAAA;EAAZ,SAAA,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAGjB,SAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAmB,SAAA,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAWtB,SAAA,YAAA,EAiHX,CAAA,QAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;;AA/DuC,cAlD5B,oBAkD4B,EAlDR,MAAA,CAAA,MAkDQ,CAAA;EAAZ,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAJU,mBAIV,GAAA,IAAA;EAMb,cAAA,EAAA,GAAA,GANa,GAMb,CAAA,MAAA,EANyB,mBAMzB,CAAA;2CAAA;EAxDiB,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAiH9B,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;;;cAAA;cAGU,uBAAA,SAAgC,4BAAA;AAKhC,cAAA,gBAGZ,EAH4B,KAAA,CAAA,KAG5B,CAH4B,uBAG5B,EAAA,KAAA,EAH4B,uBAG5B,CAAA;;;AA5IgB,cCkEJ,oBDlEoB,ECkEA,MAAA,CAAA,MDlEA,CCkEA,gBDlEA,EAAA,KAAA,ECkEA,uBDlEA,CAAA;AACU,cCsE9B,qBDtE8B,EAAA,CAAA,gBAAA,ECuEvB,KAAA,CAAM,KDvEiB,CCuEX,uBDvEW,CAAA,EAAA,GCuEa,KAAA,CAAA,KDvEb,CCuEa,uBDvEb,EAAA,KAAA,EAAA,KAAA,CAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/websocket-manager.ts","../src/websocket-event-emitter.ts"],"sourcesContent":[],"mappings":";;;;UAKiB,gBAAA;2CAC0B;EAD1B,SAAA,cAAgB,EAAA,GAAA,GAEA,GAFA,CAAA,MAAA,EAEY,mBAFZ,CAAA;EACU,SAAA,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,UAAA,EAI3B,mBAJ2B,EAAA,GAAA,IAAA;EACE,SAAA,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAZ,SAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAGjB,SAAA,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAmB,SAAA,YAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;AAWnC;AA8CuC,cA9C1B,oBA8C0B,EA9CN,MAAA,CAAA,MA8CM,CAAA;EAIE,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAJF,mBAIE,GAAA,IAAA;EAAZ,cAAA,EAAA,GAAA,GAAA,GAAA,CAAA,MAAA,EAAY,mBAAZ,CAAA;EAMb,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,GAAA,IAAA;EAxDiB,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAiH9B,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;;;cAAA;cAGU,uBAAA,SAAgC,4BAAA;AAKhC,cAAA,gBAAgB,EAAA,KAAA,CAAA,KAAA,CAAA,uBAAA,EAAA,OAAA,EAAA,OAAA,CAAA;;;AAzIZ,cCkEJ,oBDlEoB,ECkEA,MAAA,CAAA,MDlEA,CCkEA,gBDlEA,EAAA,KAAA,ECkEA,uBDlEA,CAAA;AACU,cCsE9B,qBDtE8B,EAAA,CAAA,gBAAA,ECuEvB,KAAA,CAAM,KDvEiB,CCuEX,uBDvEW,CAAA,EAAA,GCuEa,KAAA,CAAA,KDvEb,CAAA,OAAA,EAAA,OAAA,EAAA,KAAA,CAAA"}
@@ -1,4 +1,4 @@
1
- import { BaseEventEmitter, BaseEventEmitterService, EventBroadcasterService, WebSocketConnection } from "@uploadista/core/types";
1
+ import { BaseEventEmitter, EventBroadcasterService, WebSocketConnection } from "@uploadista/core/types";
2
2
  import { Context, Effect, Layer } from "effect";
3
3
 
4
4
  //#region src/websocket-manager.d.ts
@@ -19,14 +19,14 @@ declare const makeWebSocketManager: Effect.Effect<{
19
19
  subscribeToEvents: (eventKey: string, connectionId: string) => void;
20
20
  unsubscribeFromEvents: (eventKey: string, connectionId: string) => void;
21
21
  emitToEvents: (eventKey: string, message: string) => void;
22
- }, never, EventBroadcasterService>;
22
+ }, unknown, unknown>;
23
23
  declare const WebSocketManagerService_base: Context.TagClass<WebSocketManagerService, "BaseWebSocketManagerService", WebSocketManager>;
24
24
  declare class WebSocketManagerService extends WebSocketManagerService_base {}
25
- declare const webSocketManager: Layer.Layer<WebSocketManagerService, never, EventBroadcasterService>;
25
+ declare const webSocketManager: Layer.Layer<WebSocketManagerService, unknown, unknown>;
26
26
  //#endregion
27
27
  //#region src/websocket-event-emitter.d.ts
28
28
  declare const makeBaseEventEmitter: Effect.Effect<BaseEventEmitter, never, WebSocketManagerService>;
29
- declare const webSocketEventEmitter: (eventBroadcaster: Layer.Layer<EventBroadcasterService>) => Layer.Layer<BaseEventEmitterService, never, never>;
29
+ declare const webSocketEventEmitter: (eventBroadcaster: Layer.Layer<EventBroadcasterService>) => Layer.Layer<unknown, unknown, never>;
30
30
  //#endregion
31
31
  export { type WebSocketManager, WebSocketManagerService, makeBaseEventEmitter, makeWebSocketManager, webSocketEventEmitter, webSocketManager };
32
- //# sourceMappingURL=index.d.ts.map
32
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/websocket-manager.ts","../src/websocket-event-emitter.ts"],"sourcesContent":[],"mappings":";;;;UAKiB,gBAAA;2CAC0B;EAD1B,SAAA,cAAgB,EAAA,GAAA,GAEA,GAFA,CAAA,MAAA,EAEY,mBAFZ,CAAA;EACU,SAAA,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,UAAA,EAI3B,mBAJ2B,EAAA,GAAA,IAAA;EACE,SAAA,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAZ,SAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAGjB,SAAA,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAmB,SAAA,YAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;AAWnC;AA8CuC,cA9C1B,oBA8C0B,EA9CN,MAAA,CAAA,MA8CM,CAAA;EAIE,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAJF,mBAIE,GAAA,IAAA;EAAZ,cAAA,EAAA,GAAA,GAAA,GAAA,CAAA,MAAA,EAAY,mBAAZ,CAAA;EAMb,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,GAAA,IAAA;EAxDiB,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAiH9B,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;;;cAAA;cAGU,uBAAA,SAAgC,4BAAA;AAKhC,cAAA,gBAAgB,EAAA,KAAA,CAAA,KAAA,CAAA,uBAAA,EAAA,OAAA,EAAA,OAAA,CAAA;;;AAzIZ,cCkEJ,oBDlEoB,ECkEA,MAAA,CAAA,MDlEA,CCkEA,gBDlEA,EAAA,KAAA,ECkEA,uBDlEA,CAAA;AACU,cCsE9B,qBDtE8B,EAAA,CAAA,gBAAA,ECuEvB,KAAA,CAAM,KDvEiB,CCuEX,uBDvEW,CAAA,EAAA,GCuEa,KAAA,CAAA,KDvEb,CAAA,OAAA,EAAA,OAAA,EAAA,KAAA,CAAA"}
@@ -1,2 +1,2 @@
1
1
  import{UploadistaError as e}from"@uploadista/core/errors";import{BaseEventEmitterService as t,EventBroadcasterService as n}from"@uploadista/core/types";import{Context as r,Effect as i,Layer as a}from"effect";const o=i.gen(function*(){let e=yield*n,t=new Map,r=new Map,a=(e,n)=>{let i=r.get(e);if(i)for(let e of i){let r=t.get(e);if(r&&r.readyState===1)try{r.send(n)}catch(t){console.warn(`Failed to send message to connection ${e}:`,t),l(e)}else l(e)}};yield*e.subscribe(`uploadista:events`,e=>{try{let{eventKey:t,message:n}=JSON.parse(e);a(t,n)}catch(e){console.warn(`Failed to parse broadcast message:`,e)}}).pipe(i.catchAll(e=>(console.error(`Failed to subscribe to broadcast events:`,e),i.void)));let o=e=>t.get(e)||null,s=()=>t,c=(e,n)=>{t.set(e,n)},l=e=>{t.delete(e);for(let[t,n]of r.entries())n.delete(e),n.size===0&&r.delete(t)};return{getConnection:o,getConnections:s,addConnection:c,removeConnection:l,subscribeToEvents:(e,t)=>{r.has(e)||r.set(e,new Set),r.get(e)?.add(t)},unsubscribeFromEvents:(e,t)=>{let n=r.get(e);n&&(n.delete(t),n.size===0&&r.delete(e))},emitToEvents:(t,n)=>{i.runPromise(e.publish(`uploadista:events`,JSON.stringify({eventKey:t,message:n}))).catch(e=>{console.error(`Failed to publish event to broadcaster:`,e)})}}});var s=class extends r.Tag(`BaseWebSocketManagerService`)(){};const c=a.effect(s,o);function l(t){return{emit:(n,r)=>i.try({try:()=>{t.emitToEvents(n,r)},catch:t=>e.fromCode(`UNKNOWN_ERROR`,{cause:t})}),subscribe:(n,r)=>i.try({try:()=>{t.addConnection(r.id,r),t.subscribeToEvents(n,r.id),r.send(JSON.stringify({type:`subscribed`,payload:{eventKey:n},timestamp:new Date().toISOString()}))},catch:t=>e.fromCode(`UNKNOWN_ERROR`,{cause:t})}),unsubscribe:n=>i.try({try:()=>{let e=t.getConnections();for(let[r]of e)t.unsubscribeFromEvents(n,r)},catch:t=>e.fromCode(`UNKNOWN_ERROR`,{cause:t})})}}const u=i.gen(function*(){return l(yield*s)}),d=e=>a.effect(t,u).pipe(a.provide(c),a.provide(e));export{s as WebSocketManagerService,u as makeBaseEventEmitter,o as makeWebSocketManager,d as webSocketEventEmitter,c as webSocketManager};
2
- //# sourceMappingURL=index.js.map
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["webSocketManager"],"sources":["../src/websocket-manager.ts","../src/websocket-event-emitter.ts"],"sourcesContent":["import type { WebSocketConnection } from \"@uploadista/core/types\";\nimport { EventBroadcasterService } from \"@uploadista/core/types\";\nimport { Context, Effect, Layer } from \"effect\";\n\n// Base untyped WebSocketManager - works with raw string messages\nexport interface WebSocketManager {\n readonly getConnection: (key: string) => WebSocketConnection | null;\n readonly getConnections: () => Map<string, WebSocketConnection>;\n readonly addConnection: (\n key: string,\n connection: WebSocketConnection,\n ) => void;\n readonly removeConnection: (key: string) => void;\n readonly subscribeToEvents: (eventKey: string, connectionId: string) => void;\n readonly unsubscribeFromEvents: (\n eventKey: string,\n connectionId: string,\n ) => void;\n readonly emitToEvents: (eventKey: string, event: string) => void;\n}\n\nexport const makeWebSocketManager = Effect.gen(function* () {\n const broadcaster = yield* EventBroadcasterService;\n\n const connections = new Map<string, WebSocketConnection>();\n const subscriptions = new Map<string, Set<string>>(); // eventKey -> Set<connectionId>\n\n // Helper to send messages to local connections for a given eventKey\n const emitToLocalConnections = (eventKey: string, message: string): void => {\n const connectionIds = subscriptions.get(eventKey);\n if (!connectionIds) return;\n\n for (const connectionId of connectionIds) {\n const connection = connections.get(connectionId);\n if (connection && connection.readyState === 1) {\n try {\n connection.send(message);\n } catch (error) {\n console.warn(\n `Failed to send message to connection ${connectionId}:`,\n error,\n );\n removeConnection(connectionId);\n }\n } else {\n removeConnection(connectionId);\n }\n }\n };\n\n // Subscribe to broadcast events from other instances\n yield* broadcaster\n .subscribe(\"uploadista:events\", (broadcastMessage) => {\n try {\n const { eventKey, message } = JSON.parse(broadcastMessage);\n emitToLocalConnections(eventKey, message);\n } catch (error) {\n console.warn(\"Failed to parse broadcast message:\", error);\n }\n })\n .pipe(\n Effect.catchAll((error) => {\n console.error(\"Failed to subscribe to broadcast events:\", error);\n return Effect.void;\n }),\n );\n\n const getConnection = (key: string): WebSocketConnection | null => {\n return connections.get(key) || null;\n };\n\n const getConnections = (): Map<string, WebSocketConnection> => {\n return connections;\n };\n\n const addConnection = (\n key: string,\n connection: WebSocketConnection,\n ): void => {\n connections.set(key, connection);\n };\n\n const removeConnection = (key: string): void => {\n connections.delete(key);\n // Clean up subscriptions\n for (const [eventKey, connectionIds] of subscriptions.entries()) {\n connectionIds.delete(key);\n if (connectionIds.size === 0) {\n subscriptions.delete(eventKey);\n }\n }\n };\n\n const subscribeToEvents = (eventKey: string, connectionId: string): void => {\n if (!subscriptions.has(eventKey)) {\n subscriptions.set(eventKey, new Set());\n }\n subscriptions.get(eventKey)?.add(connectionId);\n };\n\n const unsubscribeFromEvents = (\n eventKey: string,\n connectionId: string,\n ): void => {\n const connectionIds = subscriptions.get(eventKey);\n if (connectionIds) {\n connectionIds.delete(connectionId);\n if (connectionIds.size === 0) {\n subscriptions.delete(eventKey);\n }\n }\n };\n\n const emitToEvents = (eventKey: string, message: string): void => {\n // Publish to broadcaster so all instances (including this one) receive it\n Effect.runPromise(\n broadcaster.publish(\n \"uploadista:events\",\n JSON.stringify({ eventKey, message }),\n ),\n ).catch((error) => {\n console.error(\"Failed to publish event to broadcaster:\", error);\n });\n };\n\n return {\n getConnection,\n getConnections,\n addConnection,\n removeConnection,\n subscribeToEvents,\n unsubscribeFromEvents,\n emitToEvents,\n };\n});\n\n// Context tags\nexport class WebSocketManagerService extends Context.Tag(\n \"BaseWebSocketManagerService\",\n)<WebSocketManagerService, WebSocketManager>() {}\n\n// Base layer\nexport const webSocketManager = Layer.effect(\n WebSocketManagerService,\n makeWebSocketManager,\n);\n","import { UploadistaError } from \"@uploadista/core/errors\";\nimport type {\n WebSocketConnection,\n WebSocketMessage,\n} from \"@uploadista/core/types\";\nimport {\n type BaseEventEmitter,\n BaseEventEmitterService,\n type EventBroadcasterService,\n} from \"@uploadista/core/types\";\nimport { Effect, Layer } from \"effect\";\nimport {\n type WebSocketManager,\n WebSocketManagerService,\n webSocketManager,\n} from \"./websocket-manager\";\n\nexport function webSocketBaseEventEmitter(\n webSocketManager: WebSocketManager,\n): BaseEventEmitter {\n return {\n emit: (eventKey: string, message: string) => {\n return Effect.try({\n try: () => {\n webSocketManager.emitToEvents(eventKey, message);\n },\n catch: (cause) => {\n return UploadistaError.fromCode(\"UNKNOWN_ERROR\", { cause });\n },\n });\n },\n subscribe: (eventKey: string, connection: WebSocketConnection) => {\n return Effect.try({\n try: () => {\n webSocketManager.addConnection(connection.id, connection);\n webSocketManager.subscribeToEvents(eventKey, connection.id);\n\n // Send confirmation message\n connection.send(\n JSON.stringify({\n type: \"subscribed\",\n payload: { eventKey },\n timestamp: new Date().toISOString(),\n } satisfies WebSocketMessage),\n );\n },\n catch: (cause) => {\n return UploadistaError.fromCode(\"UNKNOWN_ERROR\", { cause });\n },\n });\n },\n unsubscribe: (eventKey: string) => {\n return Effect.try({\n try: () => {\n // Note: We need connectionId for proper cleanup, but the interface only provides eventKey\n // For now, we'll remove all connections for this eventKey\n // This could be improved by tracking connection mapping\n const connections = webSocketManager.getConnections();\n for (const [connectionId] of connections) {\n webSocketManager.unsubscribeFromEvents(eventKey, connectionId);\n }\n },\n catch: (cause) => {\n return UploadistaError.fromCode(\"UNKNOWN_ERROR\", { cause });\n },\n });\n },\n };\n}\n\n// Effect-based implementation using webSocketManagerService\nexport const makeBaseEventEmitter = Effect.gen(function* () {\n const webSocketManager = yield* WebSocketManagerService;\n return webSocketBaseEventEmitter(webSocketManager);\n});\n\nexport const webSocketEventEmitter = (\n eventBroadcaster: Layer.Layer<EventBroadcasterService>,\n) =>\n Layer.effect(BaseEventEmitterService, makeBaseEventEmitter).pipe(\n Layer.provide(webSocketManager),\n Layer.provide(eventBroadcaster),\n );\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uploadista/event-emitter-websocket",
3
3
  "type": "module",
4
- "version": "0.0.7",
4
+ "version": "0.0.9",
5
5
  "description": "WebSocket event emitter for Uploadista",
6
6
  "license": "MIT",
7
7
  "author": "Uploadista",
@@ -13,12 +13,12 @@
13
13
  }
14
14
  },
15
15
  "dependencies": {
16
- "effect": "3.18.4",
17
- "@uploadista/core": "0.0.7"
16
+ "effect": "3.19.0",
17
+ "@uploadista/core": "0.0.9"
18
18
  },
19
19
  "devDependencies": {
20
- "tsdown": "0.15.9",
21
- "@uploadista/typescript-config": "0.0.7"
20
+ "tsdown": "0.16.0",
21
+ "@uploadista/typescript-config": "0.0.9"
22
22
  },
23
23
  "scripts": {
24
24
  "build": "tsdown",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/websocket-manager.ts","../src/websocket-event-emitter.ts"],"sourcesContent":[],"mappings":";;;;UAKiB,gBAAA;EAAA,SAAA,aAAgB,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GACU,mBADV,GAAA,IAAA;EACU,SAAA,cAAA,EAAA,GAAA,GACV,GADU,CAAA,MAAA,EACE,mBADF,CAAA;EACE,SAAA,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,UAAA,EAG7B,mBAH6B,EAAA,GAAA,IAAA;EAAZ,SAAA,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAGjB,SAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAmB,SAAA,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAWtB,SAAA,YAAA,EAiHX,CAAA,QAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;;AA/DuC,cAlD5B,oBAkD4B,EAlDR,MAAA,CAAA,MAkDQ,CAAA;EAAZ,aAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAJU,mBAIV,GAAA,IAAA;EAMb,cAAA,EAAA,GAAA,GANa,GAMb,CAAA,MAAA,EANyB,mBAMzB,CAAA;2CAAA;EAxDiB,gBAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA,iBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAiH9B,qBAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,GAAA,IAAA;;;cAAA;cAGU,uBAAA,SAAgC,4BAAA;AAKhC,cAAA,gBAGZ,EAH4B,KAAA,CAAA,KAG5B,CAH4B,uBAG5B,EAAA,KAAA,EAH4B,uBAG5B,CAAA;;;AA5IgB,cCkEJ,oBDlEoB,ECkEA,MAAA,CAAA,MDlEA,CCkEA,gBDlEA,EAAA,KAAA,ECkEA,uBDlEA,CAAA;AACU,cCsE9B,qBDtE8B,EAAA,CAAA,gBAAA,ECuEvB,KAAA,CAAM,KDvEiB,CCuEX,uBDvEW,CAAA,EAAA,GCuEa,KAAA,CAAA,KDvEb,CCuEa,uBDvEb,EAAA,KAAA,EAAA,KAAA,CAAA"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["webSocketManager"],"sources":["../src/websocket-manager.ts","../src/websocket-event-emitter.ts"],"sourcesContent":["import type { WebSocketConnection } from \"@uploadista/core/types\";\nimport { EventBroadcasterService } from \"@uploadista/core/types\";\nimport { Context, Effect, Layer } from \"effect\";\n\n// Base untyped WebSocketManager - works with raw string messages\nexport interface WebSocketManager {\n readonly getConnection: (key: string) => WebSocketConnection | null;\n readonly getConnections: () => Map<string, WebSocketConnection>;\n readonly addConnection: (\n key: string,\n connection: WebSocketConnection,\n ) => void;\n readonly removeConnection: (key: string) => void;\n readonly subscribeToEvents: (eventKey: string, connectionId: string) => void;\n readonly unsubscribeFromEvents: (\n eventKey: string,\n connectionId: string,\n ) => void;\n readonly emitToEvents: (eventKey: string, event: string) => void;\n}\n\nexport const makeWebSocketManager = Effect.gen(function* () {\n const broadcaster = yield* EventBroadcasterService;\n\n const connections = new Map<string, WebSocketConnection>();\n const subscriptions = new Map<string, Set<string>>(); // eventKey -> Set<connectionId>\n\n // Helper to send messages to local connections for a given eventKey\n const emitToLocalConnections = (eventKey: string, message: string): void => {\n const connectionIds = subscriptions.get(eventKey);\n if (!connectionIds) return;\n\n for (const connectionId of connectionIds) {\n const connection = connections.get(connectionId);\n if (connection && connection.readyState === 1) {\n try {\n connection.send(message);\n } catch (error) {\n console.warn(\n `Failed to send message to connection ${connectionId}:`,\n error,\n );\n removeConnection(connectionId);\n }\n } else {\n removeConnection(connectionId);\n }\n }\n };\n\n // Subscribe to broadcast events from other instances\n yield* broadcaster\n .subscribe(\"uploadista:events\", (broadcastMessage) => {\n try {\n const { eventKey, message } = JSON.parse(broadcastMessage);\n emitToLocalConnections(eventKey, message);\n } catch (error) {\n console.warn(\"Failed to parse broadcast message:\", error);\n }\n })\n .pipe(\n Effect.catchAll((error) => {\n console.error(\"Failed to subscribe to broadcast events:\", error);\n return Effect.void;\n }),\n );\n\n const getConnection = (key: string): WebSocketConnection | null => {\n return connections.get(key) || null;\n };\n\n const getConnections = (): Map<string, WebSocketConnection> => {\n return connections;\n };\n\n const addConnection = (\n key: string,\n connection: WebSocketConnection,\n ): void => {\n connections.set(key, connection);\n };\n\n const removeConnection = (key: string): void => {\n connections.delete(key);\n // Clean up subscriptions\n for (const [eventKey, connectionIds] of subscriptions.entries()) {\n connectionIds.delete(key);\n if (connectionIds.size === 0) {\n subscriptions.delete(eventKey);\n }\n }\n };\n\n const subscribeToEvents = (eventKey: string, connectionId: string): void => {\n if (!subscriptions.has(eventKey)) {\n subscriptions.set(eventKey, new Set());\n }\n subscriptions.get(eventKey)?.add(connectionId);\n };\n\n const unsubscribeFromEvents = (\n eventKey: string,\n connectionId: string,\n ): void => {\n const connectionIds = subscriptions.get(eventKey);\n if (connectionIds) {\n connectionIds.delete(connectionId);\n if (connectionIds.size === 0) {\n subscriptions.delete(eventKey);\n }\n }\n };\n\n const emitToEvents = (eventKey: string, message: string): void => {\n // Publish to broadcaster so all instances (including this one) receive it\n Effect.runPromise(\n broadcaster.publish(\n \"uploadista:events\",\n JSON.stringify({ eventKey, message }),\n ),\n ).catch((error) => {\n console.error(\"Failed to publish event to broadcaster:\", error);\n });\n };\n\n return {\n getConnection,\n getConnections,\n addConnection,\n removeConnection,\n subscribeToEvents,\n unsubscribeFromEvents,\n emitToEvents,\n };\n});\n\n// Context tags\nexport class WebSocketManagerService extends Context.Tag(\n \"BaseWebSocketManagerService\",\n)<WebSocketManagerService, WebSocketManager>() {}\n\n// Base layer\nexport const webSocketManager = Layer.effect(\n WebSocketManagerService,\n makeWebSocketManager,\n);\n","import { UploadistaError } from \"@uploadista/core/errors\";\nimport type {\n WebSocketConnection,\n WebSocketMessage,\n} from \"@uploadista/core/types\";\nimport {\n type BaseEventEmitter,\n BaseEventEmitterService,\n type EventBroadcasterService,\n} from \"@uploadista/core/types\";\nimport { Effect, Layer } from \"effect\";\nimport {\n type WebSocketManager,\n WebSocketManagerService,\n webSocketManager,\n} from \"./websocket-manager\";\n\nexport function webSocketBaseEventEmitter(\n webSocketManager: WebSocketManager,\n): BaseEventEmitter {\n return {\n emit: (eventKey: string, message: string) => {\n return Effect.try({\n try: () => {\n webSocketManager.emitToEvents(eventKey, message);\n },\n catch: (cause) => {\n return UploadistaError.fromCode(\"UNKNOWN_ERROR\", { cause });\n },\n });\n },\n subscribe: (eventKey: string, connection: WebSocketConnection) => {\n return Effect.try({\n try: () => {\n webSocketManager.addConnection(connection.id, connection);\n webSocketManager.subscribeToEvents(eventKey, connection.id);\n\n // Send confirmation message\n connection.send(\n JSON.stringify({\n type: \"subscribed\",\n payload: { eventKey },\n timestamp: new Date().toISOString(),\n } satisfies WebSocketMessage),\n );\n },\n catch: (cause) => {\n return UploadistaError.fromCode(\"UNKNOWN_ERROR\", { cause });\n },\n });\n },\n unsubscribe: (eventKey: string) => {\n return Effect.try({\n try: () => {\n // Note: We need connectionId for proper cleanup, but the interface only provides eventKey\n // For now, we'll remove all connections for this eventKey\n // This could be improved by tracking connection mapping\n const connections = webSocketManager.getConnections();\n for (const [connectionId] of connections) {\n webSocketManager.unsubscribeFromEvents(eventKey, connectionId);\n }\n },\n catch: (cause) => {\n return UploadistaError.fromCode(\"UNKNOWN_ERROR\", { cause });\n },\n });\n },\n };\n}\n\n// Effect-based implementation using webSocketManagerService\nexport const makeBaseEventEmitter = Effect.gen(function* () {\n const webSocketManager = yield* WebSocketManagerService;\n return webSocketBaseEventEmitter(webSocketManager);\n});\n\nexport const webSocketEventEmitter = (\n eventBroadcaster: Layer.Layer<EventBroadcasterService>,\n) =>\n Layer.effect(BaseEventEmitterService, makeBaseEventEmitter).pipe(\n Layer.provide(webSocketManager),\n Layer.provide(eventBroadcaster),\n );\n"],"mappings":"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"}