@dooboostore/simple-boot-http-server 1.0.25 → 1.0.27

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 (66) hide show
  1. package/README.md +100 -14
  2. package/dist/cjs/SimpleBootHttpServer.js +34 -18
  3. package/dist/cjs/SimpleBootHttpServer.js.map +2 -2
  4. package/dist/cjs/bundle-entry.js +34 -24
  5. package/dist/cjs/bundle-entry.js.map +2 -2
  6. package/dist/cjs/codes/Mimes.js +2 -0
  7. package/dist/cjs/codes/Mimes.js.map +2 -2
  8. package/dist/cjs/decorators/MethodMapping.js +2 -2
  9. package/dist/cjs/decorators/MethodMapping.js.map +2 -2
  10. package/dist/cjs/filters/ResourceFilter.js +0 -1
  11. package/dist/cjs/filters/ResourceFilter.js.map +2 -2
  12. package/dist/cjs/option/HttpServerOption.js.map +2 -2
  13. package/dist/cjs/proxy/TopicProtocolApiServiceProxy.js +244 -266
  14. package/dist/cjs/proxy/TopicProtocolApiServiceProxy.js.map +3 -3
  15. package/dist/cjs/websocket/WebSocketClient.js +2 -1
  16. package/dist/cjs/websocket/WebSocketClient.js.map +2 -2
  17. package/dist/cjs/websocket/WebSocketManager.js +68 -40
  18. package/dist/cjs/websocket/WebSocketManager.js.map +2 -2
  19. package/dist/esm/SimpleBootHttpServer.js +34 -18
  20. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  21. package/dist/esm/bundle-entry.js +14 -12
  22. package/dist/esm/bundle-entry.js.map +2 -2
  23. package/dist/esm/codes/Mimes.js +2 -0
  24. package/dist/esm/codes/Mimes.js.map +2 -2
  25. package/dist/esm/decorators/MethodMapping.js +2 -2
  26. package/dist/esm/decorators/MethodMapping.js.map +2 -2
  27. package/dist/esm/filters/ResourceFilter.js +0 -1
  28. package/dist/esm/filters/ResourceFilter.js.map +2 -2
  29. package/dist/esm/option/HttpServerOption.js.map +2 -2
  30. package/dist/esm/proxy/TopicProtocolApiServiceProxy.js +244 -266
  31. package/dist/esm/proxy/TopicProtocolApiServiceProxy.js.map +3 -3
  32. package/dist/esm/websocket/WebSocketClient.js +3 -2
  33. package/dist/esm/websocket/WebSocketClient.js.map +2 -2
  34. package/dist/esm/websocket/WebSocketManager.js +68 -40
  35. package/dist/esm/websocket/WebSocketManager.js.map +2 -2
  36. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +19134 -9180
  37. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
  38. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  39. package/dist/types/bundle-entry.d.ts +7 -12
  40. package/dist/types/bundle-entry.d.ts.map +1 -1
  41. package/dist/types/codes/Mimes.d.ts +2 -0
  42. package/dist/types/codes/Mimes.d.ts.map +1 -1
  43. package/dist/types/decorators/MethodMapping.d.ts +8 -0
  44. package/dist/types/decorators/MethodMapping.d.ts.map +1 -1
  45. package/dist/types/filters/ResourceFilter.d.ts.map +1 -1
  46. package/dist/types/option/HttpServerOption.d.ts +6 -2
  47. package/dist/types/option/HttpServerOption.d.ts.map +1 -1
  48. package/dist/types/proxy/TopicProtocolApiServiceProxy.d.ts +5 -15
  49. package/dist/types/proxy/TopicProtocolApiServiceProxy.d.ts.map +1 -1
  50. package/dist/types/websocket/WebSocketClient.d.ts.map +1 -1
  51. package/dist/types/websocket/WebSocketManager.d.ts +3 -1
  52. package/dist/types/websocket/WebSocketManager.d.ts.map +1 -1
  53. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +19121 -9173
  54. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
  55. package/dist/umd-bundle/websocket-client.umd.js +412 -1482
  56. package/dist/umd-bundle/websocket-client.umd.js.map +4 -4
  57. package/package.json +8 -8
  58. package/src/SimpleBootHttpServer.ts +37 -18
  59. package/src/bundle-entry.ts +12 -12
  60. package/src/codes/Mimes.ts +2 -0
  61. package/src/decorators/MethodMapping.ts +14 -7
  62. package/src/filters/ResourceFilter.ts +0 -1
  63. package/src/option/HttpServerOption.ts +4 -2
  64. package/src/proxy/TopicProtocolApiServiceProxy.ts +260 -275
  65. package/src/websocket/WebSocketClient.ts +3 -2
  66. package/src/websocket/WebSocketManager.ts +69 -41
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/proxy/TopicProtocolApiServiceProxy.ts"],
4
- "sourcesContent": ["import { getSim, Sim } from '@dooboostore/simple-boot';\nimport { HttpHeaders } from '../codes/HttpHeaders';\nimport { ApiService } from '@dooboostore/simple-boot';\nimport { RandomUtils } from '@dooboostore/core';\nimport { HttpFetcherTarget } from '@dooboostore/core';\n\nexport type TopicProtocolConfig<TBody = unknown> = {\n bypassTransform?: boolean;\n transformText?: boolean;\n headers?: HeadersInit;\n body?: TBody;\n endpoint?: HttpFetcherTarget;\n type?: TopicProtocolType;\n config?: ApiService.ApiServiceConfig;\n};\n\ntype TopicProtocolType = 'intent' | 'router';\ntype TopicProtocolRequest<TBody = unknown> = {\n type: TopicProtocolType;\n target: string;\n requestUUID: string;\n body?: TBody;\n files?: Array<{ id: string }>;\n};\n\ntype FileEntry = { id: string; file: Blob; filename?: string };\ntype MixedPart = { headers: Record<string, string>; body: Uint8Array };\n\n@Sim\nexport class TopicProtocolApiServiceProxy<T extends object> implements ProxyHandler<T> {\n constructor(private apiService: ApiService) {}\n\n private static isFileValue(value: unknown): value is File | Blob | ArrayBuffer | Uint8Array {\n if (typeof File !== 'undefined' && value instanceof File) {\n return true;\n }\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n return true;\n }\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return true;\n }\n if (typeof Uint8Array !== 'undefined' && value instanceof Uint8Array) {\n return true;\n }\n return false;\n }\n\n private static toFileEntry(value: File | Blob | ArrayBuffer | Uint8Array, id: string): FileEntry | undefined {\n if (typeof Blob === 'undefined') {\n return undefined;\n }\n if (typeof File !== 'undefined' && value instanceof File) {\n const blob = new Blob([value], { type: value.type });\n return { id, file: blob, filename: value.name };\n }\n if (value instanceof Blob) {\n return { id, file: value };\n }\n const view = value instanceof Uint8Array ? value : new Uint8Array(value);\n const safe = value instanceof Uint8Array ? new Uint8Array(value) : new Uint8Array(view);\n const blob = new Blob([safe]);\n return { id, file: blob };\n }\n\n private static buildRequest<TBody>(target: string, body?: TBody, type: TopicProtocolType = 'intent') {\n const fileEntries: FileEntry[] = [];\n let fileIndex = 0;\n\n const registerFile = (value: File | Blob | ArrayBuffer | Uint8Array): string | undefined => {\n const id = `f${++fileIndex}`;\n const entry = TopicProtocolApiServiceProxy.toFileEntry(value, id);\n if (entry) {\n fileEntries.push(entry);\n return id;\n }\n return undefined;\n };\n\n const replaceFiles = (value: unknown): unknown => {\n if (TopicProtocolApiServiceProxy.isFileValue(value)) {\n const id = registerFile(value);\n if (id) {\n return { $file: id };\n }\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(item => replaceFiles(item));\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFiles((value as Record<string, unknown>)[key]);\n });\n return result;\n }\n return value;\n };\n\n const payload = replaceFiles(body);\n const request: TopicProtocolRequest<TBody> = {\n type,\n target,\n requestUUID: RandomUtils.uuid4(),\n body: payload as TBody,\n files: fileEntries.length > 0 ? fileEntries.map(entry => ({ id: entry.id })) : undefined\n };\n\n return { request, fileEntries };\n }\n\n private static async parseMultipartMixed(response: Response) {\n const contentType = response.headers.get('Content-Type') ?? '';\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch) {\n return undefined;\n }\n const boundary = boundaryMatch[1].replace(/^\"|\"$/g, '');\n const buffer = new Uint8Array(await response.arrayBuffer());\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`);\n const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);\n const separator = new TextEncoder().encode('\\r\\n\\r\\n');\n\n const indexOf = (source: Uint8Array, needle: Uint8Array, from = 0) => {\n for (let i = from; i <= source.length - needle.length; i++) {\n let matched = true;\n for (let j = 0; j < needle.length; j++) {\n if (source[i + j] !== needle[j]) {\n matched = false;\n break;\n }\n }\n if (matched) {\n return i;\n }\n }\n return -1;\n };\n\n const parts: MixedPart[] = [];\n let cursor = indexOf(buffer, boundaryBytes, 0);\n while (cursor !== -1) {\n const nextBoundary = indexOf(buffer, boundaryBytes, cursor + boundaryBytes.length);\n const endBoundary = indexOf(buffer, endBoundaryBytes, cursor + boundaryBytes.length);\n const isFinal = endBoundary !== -1 && (endBoundary < nextBoundary || nextBoundary === -1);\n const partStart = cursor + boundaryBytes.length;\n if (isFinal) {\n break;\n }\n let headerStart = partStart;\n if (buffer[headerStart] === 13 && buffer[headerStart + 1] === 10) {\n headerStart += 2;\n }\n const headerEnd = indexOf(buffer, separator, headerStart);\n if (headerEnd === -1) {\n break;\n }\n const headerText = new TextDecoder().decode(buffer.slice(headerStart, headerEnd));\n const headers: Record<string, string> = {};\n headerText.split('\\r\\n').forEach(line => {\n const idx = line.indexOf(':');\n if (idx > -1) {\n const key = line.slice(0, idx).trim().toLowerCase();\n headers[key] = line.slice(idx + 1).trim();\n }\n });\n const bodyStart = headerEnd + separator.length;\n const bodyEnd = nextBoundary === -1 ? buffer.length : nextBoundary - 2;\n const body = buffer.slice(bodyStart, bodyEnd);\n parts.push({ headers, body });\n cursor = nextBoundary;\n }\n\n return { boundary, parts };\n }\n\n private static parseDispositionFilename(disposition?: string) {\n if (!disposition) {\n return undefined;\n }\n const match = disposition.match(/filename=\\\"?([^\\\";]+)\\\"?/i);\n return match ? match[1] : undefined;\n }\n\n private static parseDispositionName(disposition?: string) {\n if (!disposition) {\n return undefined;\n }\n const match = disposition.match(/name=\\\"?([^\\\";]+)\\\"?/i);\n return match ? match[1] : undefined;\n }\n\n private static replaceFileRefs(value: unknown, fileMap: Map<string, { name?: string; mime?: string; size: number; buffer: ArrayBuffer }>) {\n if (value && typeof value === 'object' && '$file' in value) {\n const fileKey = (value as { $file?: unknown }).$file;\n if (typeof fileKey === 'string') {\n const file = fileMap.get(fileKey);\n if (file) {\n return file;\n }\n }\n }\n if (Array.isArray(value)) {\n return value.map(item => TopicProtocolApiServiceProxy.replaceFileRefs(item, fileMap));\n }\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n Object.keys(value).forEach(key => {\n result[key] = TopicProtocolApiServiceProxy.replaceFileRefs((value as Record<string, unknown>)[key], fileMap);\n });\n return result;\n }\n return value;\n }\n\n private static normalizeResponse(value: unknown) {\n if (value && typeof value === 'object' && 'state' in value && 'body' in value) {\n const typed = value as { state?: string; body?: unknown };\n if (typed.state === 'error') {\n const message = typeof typed.body === 'object' && typed.body && 'message' in typed.body ? String((typed.body as { message?: unknown }).message) : 'TopicProtocol error';\n throw new Error(message);\n }\n return typed.body;\n }\n return value;\n }\n\n static createHandler<T extends object>(apiService: ApiService): ProxyHandler<T> {\n return {\n get(target: T, prop: string | symbol, receiver: unknown): unknown {\n const simConfig = getSim(target);\n const value = Reflect.get(target, prop, receiver);\n if (typeof value === 'function' && simConfig?.symbol) {\n return function (...args: unknown[]) {\n const f = value as Function;\n const p = (userConfig?: TopicProtocolConfig) => {\n const symbolValue = Array.isArray(simConfig.symbol) ? simConfig.symbol[0] : simConfig.symbol;\n const symbolName = (symbolValue as Symbol | undefined)?.description ?? String(symbolValue ?? simConfig.symbol);\n const targetPath = `Symbol.for(${symbolName}):/${String(prop)}`;\n const { request, fileEntries } = TopicProtocolApiServiceProxy.buildRequest(targetPath, userConfig?.body, userConfig?.type ?? 'intent');\n const formData = new FormData();\n formData.append('body', JSON.stringify(request));\n fileEntries.forEach(entry => {\n if (entry.filename) {\n formData.append(entry.id, entry.file, entry.filename);\n } else {\n formData.append(entry.id, entry.file);\n }\n });\n\n const headers = {\n ...(userConfig?.headers ?? {}),\n [HttpHeaders.XSimpleBootHttpTopicProtocol]: 'topic'\n };\n\n const endpoint = userConfig?.endpoint ?? '/';\n return apiService.post({\n target: endpoint,\n config: {\n responseTransform: userConfig?.bypassTransform\n ? 'response'\n : userConfig?.transformText\n ? 'text'\n : async (response: Response) => {\n const contentType = response.headers.get('Content-Type') ?? '';\n if (contentType.toLowerCase().includes('multipart/mixed')) {\n const parsed = await TopicProtocolApiServiceProxy.parseMultipartMixed(response);\n if (!parsed) {\n return undefined;\n }\n const fileMap = new Map<string, { name?: string; mime?: string; size: number; buffer: ArrayBuffer }>();\n let jsonBody: unknown = undefined;\n parsed.parts.forEach(part => {\n const partType = part.headers['content-type'] ?? '';\n const disposition = part.headers['content-disposition'];\n const name = TopicProtocolApiServiceProxy.parseDispositionName(disposition);\n if (partType.includes('application/json')) {\n const text = new TextDecoder().decode(part.body);\n jsonBody = text ? JSON.parse(text) : undefined;\n return;\n }\n const filename = TopicProtocolApiServiceProxy.parseDispositionFilename(disposition);\n if (name) {\n const view = part.body;\n const safe = new Uint8Array(view.byteLength);\n safe.set(view);\n fileMap.set(name, {\n name: filename,\n mime: partType || 'application/octet-stream',\n size: view.byteLength,\n buffer: safe.buffer\n });\n }\n });\n if (jsonBody) {\n const replaced = TopicProtocolApiServiceProxy.replaceFileRefs(jsonBody, fileMap);\n return TopicProtocolApiServiceProxy.normalizeResponse(replaced);\n }\n return undefined;\n }\n const text = await response.text();\n const parsed = text ? JSON.parse(text) : undefined;\n return TopicProtocolApiServiceProxy.normalizeResponse(parsed);\n },\n transformText: userConfig?.transformText,\n config: userConfig?.config,\n fetch: {\n credentials: 'include',\n headers,\n body: formData\n }\n } as any\n });\n };\n args.push(p);\n return Reflect.apply(f, target, args);\n };\n }\n return value;\n }\n };\n }\n\n get(target: T, prop: string | symbol, receiver: unknown): unknown {\n return TopicProtocolApiServiceProxy.createHandler<T>(this.apiService).get!(target, prop, receiver);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_simple_boot", "TopicProtocolApiServiceProxy", "blob", "parsed", "text"]
4
+ "sourcesContent": ["import { getSim, sim, SimConfig } from '@dooboostore/simple-boot';\nimport { HttpHeaders } from '../codes/HttpHeaders';\nimport { ApiService } from '@dooboostore/simple-boot';\nimport { ConstructorType, RandomUtils } from '@dooboostore/core';\nimport { HttpFetcherTarget } from '@dooboostore/core';\n\nexport type TopicProtocolConfig<TBody = unknown> = {\n bypassTransform?: boolean;\n transformText?: boolean;\n headers?: HeadersInit;\n body?: TBody;\n endpoint?: HttpFetcherTarget;\n type?: TopicProtocolType;\n config?: ApiService.ApiServiceConfig;\n};\n\ntype TopicProtocolType = 'intent' | 'router';\ntype TopicProtocolRequest<TBody = unknown> = {\n type: TopicProtocolType;\n target: string;\n requestUUID: string;\n body?: TBody;\n files?: Array<{ id: string }>;\n};\n\ntype FileEntry = { id: string; file: Blob; filename?: string };\ntype MixedPart = { headers: Record<string, string>; body: Uint8Array };\n\n// ── Helpers (module-level, mirrors SymbolIntentApiServiceProxy pattern) ──────\n\nconst isFileValue = (value: unknown): value is File | Blob | ArrayBuffer | Uint8Array => {\n if (typeof File !== 'undefined' && value instanceof File) return true;\n if (typeof Blob !== 'undefined' && value instanceof Blob) return true;\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) return true;\n if (typeof Uint8Array !== 'undefined' && value instanceof Uint8Array) return true;\n return false;\n};\n\nconst toFileEntry = (value: File | Blob | ArrayBuffer | Uint8Array, id: string): FileEntry | undefined => {\n if (typeof Blob === 'undefined') return undefined;\n if (typeof File !== 'undefined' && value instanceof File) {\n return { id, file: new Blob([value], { type: value.type }), filename: value.name };\n }\n if (value instanceof Blob) return { id, file: value };\n const safe = value instanceof Uint8Array ? new Uint8Array(value) : new Uint8Array(value);\n return { id, file: new Blob([safe]) };\n};\n\nconst buildRequest = <TBody>(target: string, body?: TBody, type: TopicProtocolType = 'intent') => {\n const fileEntries: FileEntry[] = [];\n let fileIndex = 0;\n\n const registerFile = (value: File | Blob | ArrayBuffer | Uint8Array): string | undefined => {\n const id = `f${++fileIndex}`;\n const entry = toFileEntry(value, id);\n if (entry) { fileEntries.push(entry); return id; }\n return undefined;\n };\n\n const replaceFiles = (value: unknown): unknown => {\n if (isFileValue(value)) {\n const id = registerFile(value);\n return id ? { $file: id } : value;\n }\n if (Array.isArray(value)) return value.map(item => replaceFiles(item));\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFiles((value as Record<string, unknown>)[key]);\n });\n return result;\n }\n return value;\n };\n\n const payload = replaceFiles(body);\n const request: TopicProtocolRequest<TBody> = {\n type,\n target,\n requestUUID: RandomUtils.uuid4(),\n body: payload as TBody,\n files: fileEntries.length > 0 ? fileEntries.map(e => ({ id: e.id })) : undefined,\n };\n\n return { request, fileEntries };\n};\n\nconst parseDispositionName = (disposition?: string) => {\n const match = disposition?.match(/name=\\\"?([^\\\";]+)\\\"?/i);\n return match ? match[1] : undefined;\n};\n\nconst parseDispositionFilename = (disposition?: string) => {\n const match = disposition?.match(/filename=\\\"?([^\\\";]+)\\\"?/i);\n return match ? match[1] : undefined;\n};\n\nconst parseMultipartMixed = async (response: Response) => {\n const contentType = response.headers.get('Content-Type') ?? '';\n const boundaryMatch = contentType.match(/boundary=([^;]+)/i);\n if (!boundaryMatch) return undefined;\n\n const boundary = boundaryMatch[1].replace(/^\"|\"$/g, '');\n const buffer = new Uint8Array(await response.arrayBuffer());\n const boundaryBytes = new TextEncoder().encode(`--${boundary}`);\n const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);\n const separator = new TextEncoder().encode('\\r\\n\\r\\n');\n\n const indexOf = (source: Uint8Array, needle: Uint8Array, from = 0) => {\n for (let i = from; i <= source.length - needle.length; i++) {\n let matched = true;\n for (let j = 0; j < needle.length; j++) {\n if (source[i + j] !== needle[j]) { matched = false; break; }\n }\n if (matched) return i;\n }\n return -1;\n };\n\n const parts: MixedPart[] = [];\n let cursor = indexOf(buffer, boundaryBytes, 0);\n\n while (cursor !== -1) {\n const nextBoundary = indexOf(buffer, boundaryBytes, cursor + boundaryBytes.length);\n const endBoundary = indexOf(buffer, endBoundaryBytes, cursor + boundaryBytes.length);\n const isFinal = endBoundary !== -1 && (endBoundary < nextBoundary || nextBoundary === -1);\n const partStart = cursor + boundaryBytes.length;\n if (isFinal) break;\n\n let headerStart = partStart;\n if (buffer[headerStart] === 13 && buffer[headerStart + 1] === 10) headerStart += 2;\n\n const headerEnd = indexOf(buffer, separator, headerStart);\n if (headerEnd === -1) break;\n\n const headerText = new TextDecoder().decode(buffer.slice(headerStart, headerEnd));\n const headers: Record<string, string> = {};\n headerText.split('\\r\\n').forEach(line => {\n const idx = line.indexOf(':');\n if (idx > -1) headers[line.slice(0, idx).trim().toLowerCase()] = line.slice(idx + 1).trim();\n });\n\n const bodyStart = headerEnd + separator.length;\n const bodyEnd = nextBoundary === -1 ? buffer.length : nextBoundary - 2;\n parts.push({ headers, body: buffer.slice(bodyStart, bodyEnd) });\n cursor = nextBoundary;\n }\n\n return { boundary, parts };\n};\n\nconst replaceFileRefs = (\n value: unknown,\n fileMap: Map<string, { name?: string; mime?: string; size: number; buffer: ArrayBuffer }>,\n): unknown => {\n if (value && typeof value === 'object' && '$file' in value) {\n const fileKey = (value as { $file?: unknown }).$file;\n if (typeof fileKey === 'string') {\n const file = fileMap.get(fileKey);\n if (file) return file;\n }\n }\n if (Array.isArray(value)) return value.map(item => replaceFileRefs(item, fileMap));\n if (value && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFileRefs((value as Record<string, unknown>)[key], fileMap);\n });\n return result;\n }\n return value;\n};\n\nconst normalizeResponse = (value: unknown): unknown => {\n if (value && typeof value === 'object' && 'state' in value && 'body' in value) {\n const typed = value as { state?: string; body?: unknown };\n if (typed.state === 'error') {\n const message = typeof typed.body === 'object' && typed.body && 'message' in typed.body\n ? String((typed.body as { message?: unknown }).message)\n : 'TopicProtocol error';\n throw new Error(message);\n }\n return typed.body;\n }\n return value;\n};\n\n// ── createHandler (module-level export, same as SymbolIntentApiServiceProxy) ─\n\nexport const createTopicHandler = <T extends object>(apiService: ApiService): ProxyHandler<T> => {\n return {\n get(target: T, prop: string | symbol, receiver: unknown): unknown {\n if (prop === '_SimpleBoot_origin') return target;\n\n const simConfig = getSim(target);\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof value === 'function' && simConfig?.symbol) {\n return function (...args: unknown[]) {\n const f = value as Function;\n\n const p = (userConfig?: TopicProtocolConfig) => {\n const symbolValue = Array.isArray(simConfig.symbol) ? simConfig.symbol[0] : simConfig.symbol;\n const symbolName = (symbolValue as Symbol | undefined)?.description ?? String(symbolValue ?? simConfig.symbol);\n const targetPath = `Symbol.for(${symbolName}):/${String(prop)}`;\n\n const { request, fileEntries } = buildRequest(targetPath, userConfig?.body, userConfig?.type ?? 'intent');\n\n const formData = new FormData();\n formData.append('body', JSON.stringify(request));\n fileEntries.forEach(entry => {\n if (entry.filename) formData.append(entry.id, entry.file, entry.filename);\n else formData.append(entry.id, entry.file);\n });\n\n const headers: Record<string, string> = {\n ...(userConfig?.headers as Record<string, string> ?? {}),\n [HttpHeaders.XSimpleBootHttpTopicProtocol]: 'topic',\n };\n\n const endpoint = userConfig?.endpoint ?? '/';\n\n return (apiService as any).post({\n target: endpoint,\n config: {\n responseTransform: userConfig?.bypassTransform\n ? 'response'\n : userConfig?.transformText\n ? 'text'\n : async (response: Response) => {\n const ct = response.headers.get('Content-Type') ?? '';\n if (ct.toLowerCase().includes('multipart/mixed')) {\n const parsed = await parseMultipartMixed(response);\n if (!parsed) return undefined;\n\n const fileMap = new Map<string, { name?: string; mime?: string; size: number; buffer: ArrayBuffer }>();\n let jsonBody: unknown = undefined;\n\n parsed.parts.forEach(part => {\n const partType = part.headers['content-type'] ?? '';\n const disposition = part.headers['content-disposition'];\n const name = parseDispositionName(disposition);\n\n if (partType.includes('application/json')) {\n const text = new TextDecoder().decode(part.body);\n jsonBody = text ? JSON.parse(text) : undefined;\n return;\n }\n if (name) {\n const filename = parseDispositionFilename(disposition);\n const safe = new Uint8Array(part.body.byteLength);\n safe.set(part.body);\n fileMap.set(name, {\n name: filename,\n mime: partType || 'application/octet-stream',\n size: part.body.byteLength,\n buffer: safe.buffer,\n });\n }\n });\n\n if (jsonBody) return normalizeResponse(replaceFileRefs(jsonBody, fileMap));\n return undefined;\n }\n\n const text = await response.text();\n const parsed = text ? JSON.parse(text) : undefined;\n return normalizeResponse(parsed);\n },\n transformText: userConfig?.transformText,\n config: userConfig?.config,\n fetch: {\n credentials: 'include',\n headers,\n body: formData,\n },\n } as any,\n });\n };\n\n args.push(p);\n return Reflect.apply(f, target, args);\n };\n }\n\n return Reflect.get(target, prop, receiver);\n },\n\n apply(target: T, thisArg: unknown, argArray: unknown[]): unknown {\n console.log('TopicProtocolApiServiceProxy apply');\n return Reflect.apply(target as any, thisArg, argArray as any[]);\n },\n };\n};\n\n// ── Default factory export (same shape as SymbolIntentApiServiceProxy) ───────\n\nexport default (config?: SimConfig): ConstructorType<any> => {\n @sim(config)\n class TopicProtocolApiServiceProxy<T extends object> implements ProxyHandler<T> {\n constructor(private apiService: ApiService) {}\n\n get(target: T, prop: string | symbol, receiver: unknown): unknown {\n return createTopicHandler<T>(this.apiService).get!(target, prop, receiver);\n }\n\n apply(target: T, thisArg: unknown, argArray: unknown[]): unknown {\n return createTopicHandler<T>(this.apiService).apply!(target, thisArg, argArray as any[]);\n }\n }\n\n return TopicProtocolApiServiceProxy;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_simple_boot", "parsed", "text"]
7
7
  }
@@ -23,6 +23,7 @@ __export(WebSocketClient_exports, {
23
23
  module.exports = __toCommonJS(WebSocketClient_exports);
24
24
  var import_core = require("@dooboostore/core");
25
25
  var import_core2 = require("@dooboostore/core");
26
+ var import_operators = require("@dooboostore/core/message/operators");
26
27
  __reExport(WebSocketClient_exports, require("@dooboostore/core"), module.exports);
27
28
  class WebSocketClient {
28
29
  constructor(connection, config) {
@@ -489,7 +490,7 @@ class WebSocketClient {
489
490
  const value = { type: option?.type, uuid, requestUUID, body };
490
491
  self.sendMessage(value);
491
492
  }
492
- return topicSubject.pipe(import_core2.MessageOperator.filter((data) => data && data.requestUUID === requestUUID));
493
+ return topicSubject.pipe((0, import_operators.filter)((data) => data && data.requestUUID === requestUUID));
493
494
  },
494
495
  onUnsubscribe: (callback) => {
495
496
  onUnsubscribes.push(callback);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/websocket/WebSocketClient.ts"],
4
- "sourcesContent": ["import {RandomUtils} from '@dooboostore/core';\nimport {TopicRequest, TopicResponse, TopicServerEventRequest, TopicServerEventResponse, TopicServerEventUnSubscribeRequest, TopicSubscribeRequest, TopicType, TopicUnsubscribeRequest} from './WebSocketManager';\nimport {MessageOperator, Observable, Subject} from '@dooboostore/core';\n\nexport * from '@dooboostore/core';\n\ntype TopicObserverNextCallBack<T> = <R = any>(data: T, meta: { socket: WebSocket }) => void;\ntype TopicObserverEventCallBack = { [event: string]: <T, R = any>(data: T, meta: { socket: WebSocket }) => Promise<R> | void | any } | (<T, R = any>(event: string, data: T, meta: { socket: WebSocket }) => Promise<R> | void | any);\ntype TopicObserverErrorCallBack = <R = any>(err: any) => void;\nexport type TopicObserverCallBack<T> = { next: TopicObserverNextCallBack<T>; event?: TopicObserverEventCallBack; error?: TopicObserverErrorCallBack; complete?: () => void } | TopicObserverNextCallBack<T>;\n\nexport interface WebSocketClientConfig {\n retryConnectionCount?: number;\n retryConnectionDelay?: number;\n maxPendingMessages?: number;\n maxPendingBinaryMessages?: number;\n}\n\ntype OnUnsubscribeCallback = (type: 'server' | 'manual') => void;\nexport type Subscription = {\n closed: boolean;\n unsubscribe: () => void;\n};\n\nexport class WebSocketClient {\n private websocket: WebSocket;\n private topics = new Map<string, { observer: TopicObserverCallBack<any>; subscription: Subscription; onUnsubscribes: OnUnsubscribeCallback[]; target: string }>();\n private observer?: (data: TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest) => void;\n private pendingMessages: any[] = [];\n private pendingBinaryMessages: Array<ArrayBuffer | Blob | Uint8Array> = [];\n private isConnected = false;\n private onOpenCallback: () => void;\n private onCloseCallback: () => void;\n private _subject = new Subject<TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest>();\n // Reconnection properties\n private connectionUrl: string | URL;\n private connectionProtocols?: string | string[];\n private retryConnectionCount: number;\n private retryConnectionDelay: number;\n private currentRetryCount = 0;\n private reconnectTimeout?: number;\n private isManualClose = false;\n private isConnecting = false;\n private maxPendingMessages: number;\n private maxPendingBinaryMessages: number;\n\n constructor(connection: { url: string | URL; protocols?: string | string[] }, config?: WebSocketClientConfig);\n constructor(connection: string, config?: WebSocketClientConfig);\n constructor(connection: URL, config?: WebSocketClientConfig);\n constructor(connection: { url: string | URL; protocols?: string | string[] } | string | URL, config?: WebSocketClientConfig) {\n // Store connection info for reconnection\n if (typeof connection === 'string' || connection instanceof URL) {\n this.connectionUrl = connection;\n } else {\n this.connectionUrl = connection.url;\n this.connectionProtocols = connection.protocols;\n }\n\n // Set config with defaults\n this.retryConnectionCount = config?.retryConnectionCount ?? 0;\n this.retryConnectionDelay = config?.retryConnectionDelay ?? 1000;\n this.maxPendingMessages = config?.maxPendingMessages ?? 1000;\n this.maxPendingBinaryMessages = config?.maxPendingBinaryMessages ?? 100;\n\n this.connect();\n }\n\n private get observable() {\n return this._subject.asObservable();\n }\n\n private connect() {\n if (this.isConnecting) {\n return;\n }\n if (this.websocket && (this.websocket.readyState === WebSocket.OPEN || this.websocket.readyState === WebSocket.CONNECTING)) {\n return;\n }\n this.isConnecting = true;\n if (this.connectionProtocols) {\n this.websocket = new WebSocket(this.connectionUrl, this.connectionProtocols);\n } else {\n this.websocket = new WebSocket(this.connectionUrl);\n }\n\n this.websocket.binaryType = 'arraybuffer';\n\n this.websocket.addEventListener('open', () => {\n this.isConnecting = false;\n this.isConnected = true;\n this.currentRetryCount = 0; // Reset retry count on successful connection\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = undefined;\n }\n console.log('WebSocket connected');\n this.onOpenCallback?.();\n\n // Re-subscribe to all existing topics after reconnection\n this.topics.forEach((topicData, uuid) => {\n // closed\uB41C subscription\uC740 \uC7AC\uAD6C\uB3C5\uD558\uC9C0 \uC54A\uC74C\n if (!topicData.subscription.closed) {\n const subscribeTopic: TopicSubscribeRequest = {\n type: 'subscribe',\n uuid,\n target: topicData.target\n };\n // console.log('????')\n this.websocket.send(JSON.stringify(subscribeTopic));\n }\n });\n\n // \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uBA54\uC2DC\uC9C0 \uC804\uC1A1\n while (this.pendingMessages.length > 0) {\n const message = this.pendingMessages.shift();\n this.websocket.send(JSON.stringify(message));\n }\n\n while (this.pendingBinaryMessages.length > 0) {\n const message = this.pendingBinaryMessages.shift();\n if (message) {\n this.websocket.send(message);\n }\n }\n });\n\n this.websocket.addEventListener('close', event => {\n this.isConnecting = false;\n this.isConnected = false;\n console.log('WebSocket closed', event.code, event.reason);\n this.onCloseCallback?.();\n\n // Attempt reconnection if not manually closed\n if (!this.isManualClose) {\n this.attemptReconnect();\n }\n });\n\n this.websocket.addEventListener('error', error => {\n console.error('WebSocket error:', error);\n });\n\n this.websocket.addEventListener('message', async event => {\n const topic = await this.parseIncomingTopic(event.data);\n if (!topic) {\n return;\n }\n this._subject.next(topic);\n this.observer?.(topic);\n if (topic.uuid) {\n const topicData = this.topics.get(topic.uuid);\n if (topicData) {\n const observer = topicData.observer;\n const nextCallback = typeof observer === 'function' ? observer : observer.next;\n const errorCallback = typeof observer === 'function' ? undefined : observer.error;\n const eventCallback = typeof observer === 'function' ? undefined : observer.event;\n if ('state' in topic && topic.state === 'success') {\n await nextCallback(topic.body, { socket: this.websocket });\n } else if ('state' in topic && topic.state === 'error' && errorCallback) {\n await errorCallback(topic.body);\n } else if ('type' in topic && topic.type === 'unsubscribe') {\n topicData.subscription.closed = true;\n this.topics.delete(topic.uuid);\n topicData.onUnsubscribes.forEach(it => it('server'));\n } else if ('type' in topic && topic.type === 'event' && eventCallback) {\n /////////// event ///////////\n let eventResponse = typeof eventCallback === 'function' ? await eventCallback(topic.event, topic.body, { socket: this.websocket }) : await eventCallback[topic.event]?.(topic.body, { socket: this.websocket });\n\n if (eventResponse !== undefined && eventResponse !== null) {\n const value: TopicServerEventResponse = {\n uuid: topic.uuid,\n eventUUID: topic.eventUUID,\n type: topic.type,\n body: eventResponse\n };\n this.websocket.send(JSON.stringify(value));\n }\n }\n }\n }\n });\n }\n\n private attemptReconnect() {\n if (this.currentRetryCount >= this.retryConnectionCount) {\n console.error(`WebSocket reconnection failed after ${this.retryConnectionCount} attempts`);\n return;\n }\n if (this.reconnectTimeout) {\n return;\n }\n\n this.currentRetryCount++;\n console.log(`Attempting to reconnect... (${this.currentRetryCount}/${this.retryConnectionCount})`);\n\n this.reconnectTimeout = window.setTimeout(() => {\n this.reconnectTimeout = undefined;\n this.connect();\n // Subscribe messages are already in pendingMessages and will be sent automatically\n }, this.retryConnectionDelay);\n }\n\n private sendMessage(message: TopicRequest | TopicUnsubscribeRequest | TopicSubscribeRequest) {\n if (this.isConnected && this.websocket.readyState === WebSocket.OPEN) {\n this.websocket.send(JSON.stringify(message));\n return;\n }\n if (message.type === 'subscribe' || message.type === 'unsubscribe') {\n return;\n }\n if (this.maxPendingMessages <= 0) {\n return;\n }\n if (this.pendingMessages.length >= this.maxPendingMessages) {\n this.pendingMessages.shift();\n }\n this.pendingMessages.push(message);\n }\n\n sendBinary(data: ArrayBuffer | Blob | Uint8Array) {\n if (this.isConnected && this.websocket.readyState === WebSocket.OPEN) {\n this.websocket.send(data);\n return;\n }\n if (this.maxPendingBinaryMessages <= 0) {\n return;\n }\n if (this.pendingBinaryMessages.length >= this.maxPendingBinaryMessages) {\n this.pendingBinaryMessages.shift();\n }\n this.pendingBinaryMessages.push(data);\n }\n\n private async parseIncomingTopic(data: any): Promise<TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest | undefined> {\n if (typeof data === 'string') {\n try {\n return JSON.parse(data);\n } catch (error) {\n console.warn('Invalid WebSocket payload:', error);\n return undefined;\n }\n }\n\n if (data instanceof ArrayBuffer) {\n return this.parseBinaryTopic(data);\n }\n\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n const buffer = await data.arrayBuffer();\n return this.parseBinaryTopic(buffer);\n }\n\n return undefined;\n }\n\n private parseBinaryTopic(data: ArrayBuffer): TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest | undefined {\n if (data.byteLength < 4) {\n return undefined;\n }\n const view = new DataView(data);\n const jsonLength = view.getUint32(0, true);\n const jsonStart = 4;\n const jsonEnd = jsonStart + jsonLength;\n if (data.byteLength < jsonEnd) {\n return undefined;\n }\n\n const jsonBytes = new Uint8Array(data, jsonStart, jsonLength);\n let meta: any;\n try {\n const decoder = new TextDecoder();\n meta = JSON.parse(decoder.decode(jsonBytes));\n } catch (error) {\n console.warn('Invalid WebSocket binary payload:', error);\n return undefined;\n }\n\n const filesMeta = Array.isArray(meta.files) ? meta.files : [];\n const fileMap = new Map<string, any>();\n filesMeta.forEach((file: any) => {\n if (!file || typeof file.id !== 'string' || typeof file.size !== 'number' || typeof file.offset !== 'number') {\n return;\n }\n const start = jsonEnd + file.offset;\n const end = start + file.size;\n if (start < jsonEnd || end > data.byteLength) {\n return;\n }\n const slice = data.slice(start, end);\n const mime = file.mime || 'application/octet-stream';\n let fileValue: any;\n if (typeof File !== 'undefined') {\n fileValue = new File([slice], file.name || 'file', { type: mime });\n } else {\n fileValue = { name: file.name || 'file', mime, size: file.size, buffer: slice };\n }\n fileMap.set(file.id, fileValue);\n });\n\n const replaceFileRefs = (value: any): any => {\n if (value && typeof value === 'object' && '$file' in value && typeof value.$file === 'string') {\n const file = fileMap.get(value.$file);\n if (file) {\n return file;\n }\n }\n if (Array.isArray(value)) {\n return value.map(item => replaceFileRefs(item));\n }\n if (value && typeof value === 'object') {\n const result: Record<string, any> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFileRefs(value[key]);\n });\n return result;\n }\n return value;\n };\n\n meta.body = replaceFileRefs(meta.body);\n return meta as TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest;\n }\n\n private isBinaryPayload(value: any) {\n if (!value) {\n return false;\n }\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return true;\n }\n if (typeof Uint8Array !== 'undefined' && value instanceof Uint8Array) {\n return true;\n }\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n return true;\n }\n if (value && typeof value === 'object' && 'buffer' in value) {\n const bufferValue = (value as any).buffer;\n return this.isBinaryPayload(bufferValue);\n }\n return false;\n }\n\n private hasBinaryPayload(value: any): boolean {\n if (this.isBinaryPayload(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.some(item => this.hasBinaryPayload(item));\n }\n if (value && typeof value === 'object') {\n return Object.keys(value).some(key => this.hasBinaryPayload(value[key]));\n }\n return false;\n }\n\n private async buildBinaryMessage(body: any, meta: { type?: TopicType; uuid: string; requestUUID: string }) {\n const fileRefs = new Map<any, string>();\n const fileEntries: Array<{ id: string; name: string; mime: string; buffer: Promise<ArrayBuffer | SharedArrayBuffer> }> = [];\n let fileIndex = 0;\n\n const registerFile = (value: any) => {\n const existing = fileRefs.get(value);\n if (existing) {\n return existing;\n }\n const id = `f${++fileIndex}`;\n fileRefs.set(value, id);\n\n let name = 'file';\n let mime = 'application/octet-stream';\n let buffer: Promise<ArrayBuffer | SharedArrayBuffer>;\n\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n const fileLike = value as File | Blob;\n if ('name' in fileLike && typeof (fileLike as File).name === 'string') {\n name = (fileLike as File).name || name;\n }\n mime = fileLike.type || mime;\n buffer = fileLike.arrayBuffer();\n } else if (value && typeof value === 'object' && 'buffer' in value) {\n const fileLike = value as any;\n if (typeof fileLike.name === 'string') {\n name = fileLike.name || name;\n }\n if (typeof fileLike.mime === 'string') {\n mime = fileLike.mime || mime;\n }\n const innerBuffer = fileLike.buffer;\n if (typeof Blob !== 'undefined' && innerBuffer instanceof Blob) {\n buffer = innerBuffer.arrayBuffer();\n } else if (typeof Uint8Array !== 'undefined' && innerBuffer instanceof Uint8Array) {\n const sliced = innerBuffer.buffer.slice(innerBuffer.byteOffset, innerBuffer.byteOffset + innerBuffer.byteLength);\n buffer = Promise.resolve(sliced instanceof ArrayBuffer ? sliced : new Uint8Array(sliced).buffer);\n } else if (typeof ArrayBuffer !== 'undefined' && innerBuffer instanceof ArrayBuffer) {\n buffer = Promise.resolve(innerBuffer as ArrayBuffer);\n } else {\n buffer = Promise.resolve(new ArrayBuffer(0));\n }\n } else if (typeof Uint8Array !== 'undefined' && value instanceof Uint8Array) {\n const view = value as Uint8Array;\n const sliced = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);\n buffer = Promise.resolve(sliced instanceof ArrayBuffer ? sliced : new Uint8Array(sliced).buffer);\n } else if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n buffer = Promise.resolve(value as ArrayBuffer);\n } else {\n buffer = Promise.resolve(new ArrayBuffer(0));\n }\n\n fileEntries.push({ id, name, mime, buffer });\n return id;\n };\n\n const replaceFiles = (value: any): any => {\n if (this.isBinaryPayload(value)) {\n const id = registerFile(value);\n return { $file: id };\n }\n if (Array.isArray(value)) {\n return value.map(item => replaceFiles(item));\n }\n if (value && typeof value === 'object') {\n const result: Record<string, any> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFiles(value[key]);\n });\n return result;\n }\n return value;\n };\n\n const payload = replaceFiles(body);\n const buffers = await Promise.all(fileEntries.map(entry => entry.buffer));\n\n let offset = 0;\n const files = fileEntries.map((entry, index) => {\n const size = buffers[index].byteLength;\n const fileMeta = {\n id: entry.id,\n name: entry.name,\n mime: entry.mime,\n size,\n offset\n };\n offset += size;\n return fileMeta;\n });\n\n const json = JSON.stringify({\n type: meta.type,\n uuid: meta.uuid,\n requestUUID: meta.requestUUID,\n body: payload,\n files\n });\n\n const encoder = new TextEncoder();\n const jsonBytes = encoder.encode(json);\n const header = new Uint8Array(4);\n new DataView(header.buffer).setUint32(0, jsonBytes.byteLength, true);\n\n const totalSize = header.byteLength + jsonBytes.byteLength + offset;\n const combined = new Uint8Array(totalSize);\n combined.set(header, 0);\n combined.set(jsonBytes, header.byteLength);\n\n let cursor = header.byteLength + jsonBytes.byteLength;\n buffers.forEach(buffer => {\n const view = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : new Uint8Array(buffer);\n combined.set(view, cursor);\n cursor += buffer.byteLength;\n });\n\n return combined.buffer;\n }\n\n subject(target: string, option?: { type?: TopicType; subScribeBody?: any; observer?: TopicObserverCallBack<any>; onUnsubscribe?: OnUnsubscribeCallback }) {\n const self = this;\n const uuid = RandomUtils.uuid4();\n const onUnsubscribes: OnUnsubscribeCallback[] = [];\n if (option?.onUnsubscribe) {\n onUnsubscribes.push(option.onUnsubscribe);\n }\n if (option?.observer && typeof option.observer !== 'function' && option.observer.complete) {\n onUnsubscribes.push(() => (option.observer as any).complete());\n }\n const topicSubject = new Subject<any>();\n onUnsubscribes.push(() => topicSubject.complete());\n\n let isClosed = false;\n let activeSubscription: Subscription | undefined;\n\n const unsubscribeLogic = () => {\n if (isClosed) return;\n const unSubscribeTopic: TopicUnsubscribeRequest = { type: 'unsubscribe', uuid };\n self.sendMessage(unSubscribeTopic);\n isClosed = true;\n self.topics.delete(uuid);\n onUnsubscribes.forEach(it => it('manual'));\n if (activeSubscription) {\n activeSubscription.closed = true;\n }\n };\n\n const doSubscribe = <T>(observer?: TopicObserverCallBack<T>) => {\n const subscription: Subscription = {\n closed: isClosed,\n unsubscribe: unsubscribeLogic\n };\n\n const wrappedObserver: TopicObserverCallBack<T> = {\n next: (data, meta) => {\n topicSubject.next(data);\n if (observer) {\n return typeof observer === 'function' ? observer(data, meta) : observer.next(data, meta);\n }\n },\n error: err => {\n topicSubject.error(err);\n if (observer && typeof observer !== 'function' && observer.error) {\n observer.error(err);\n }\n },\n event: observer && typeof observer !== 'function' ? observer.event : undefined\n };\n\n self.topics.set(uuid, { observer: wrappedObserver, target, subscription, onUnsubscribes });\n const subscribeTopic: TopicSubscribeRequest = { type: 'subscribe', uuid, target: target, body: option?.subScribeBody };\n\n self.sendMessage(subscribeTopic);\n // console.log('----------')\n activeSubscription = subscription;\n return subscription;\n };\n\n if (option?.observer) {\n doSubscribe(option.observer);\n }\n\n return {\n get closed() {\n return isClosed;\n },\n unsubscribe: unsubscribeLogic,\n get observable() {\n return new Observable<any>(subscriber => {\n if (!activeSubscription && !isClosed) {\n doSubscribe();\n }\n return topicSubject.subscribe({\n next: value => subscriber.next(value),\n error: err => subscriber.error(err),\n complete: () => subscriber.complete()\n });\n });\n },\n send: (body?: any) => {\n if (!activeSubscription && !self.topics.has(uuid) && !isClosed) {\n doSubscribe();\n }\n const requestUUID = RandomUtils.uuid4();\n if (self.hasBinaryPayload(body)) {\n self.buildBinaryMessage(body, { type: option?.type, uuid, requestUUID }).then(buffer => self.sendBinary(buffer));\n } else {\n const value: TopicRequest = { type: option?.type, uuid, requestUUID, body: body };\n self.sendMessage(value);\n }\n return topicSubject.pipe(MessageOperator.filter(data => data && data.requestUUID === requestUUID));\n },\n onUnsubscribe: (callback: OnUnsubscribeCallback) => {\n onUnsubscribes.push(callback);\n }\n };\n }\n\n onOpen(callback: () => void) {\n this.onOpenCallback = callback;\n }\n\n onClose(callback: () => void) {\n this.onCloseCallback = callback;\n }\n\n subscribe<T = any>(observer: (data: TopicResponse<T> | TopicServerEventRequest<T>) => void) {\n this.observer = observer;\n }\n\n close() {\n this.isManualClose = true;\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = undefined;\n }\n this.pendingMessages = [];\n this.pendingBinaryMessages = [];\n this.isConnecting = false;\n this.topics.forEach(topicData => {\n topicData.subscription.closed = true;\n topicData.onUnsubscribes.forEach(it => it('manual'));\n });\n this.topics.clear();\n this.websocket.close();\n }\n\n reconnect() {\n // \uAE30\uC874 \uC5F0\uACB0 \uC885\uB8CC\n this.isManualClose = true;\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n }\n\n // close \uC774\uBCA4\uD2B8 \uD6C4\uC5D0 \uC7AC\uC5F0\uACB0\uD558\uB3C4\uB85D \uC124\uC815\n const reconnectAfterClose = () => {\n console.log('close websocket');\n this.isManualClose = false;\n this.currentRetryCount = 0;\n this.connect();\n };\n\n // \uC774\uBBF8 \uB2EB\uD600\uC788\uC73C\uBA74 \uBC14\uB85C \uC7AC\uC5F0\uACB0\n if (this.websocket.readyState === WebSocket.CLOSED || this.websocket.readyState === WebSocket.CLOSING) {\n reconnectAfterClose();\n } else {\n // \uC5F0\uACB0\uC774 \uB2EB\uD790 \uB54C\uAE4C\uC9C0 \uAE30\uB2E4\uB838\uB2E4\uAC00 \uC7AC\uC5F0\uACB0\n this.websocket.addEventListener('close', reconnectAfterClose, { once: true });\n this.websocket.close();\n }\n }\n\n getReadyState(): number {\n return this.websocket.readyState;\n }\n\n isConnectionOpen(): boolean {\n return this.isConnected && this.websocket.readyState === WebSocket.OPEN;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {RandomUtils} from '@dooboostore/core';\nimport {TopicRequest, TopicResponse, TopicServerEventRequest, TopicServerEventResponse, TopicServerEventUnSubscribeRequest, TopicSubscribeRequest, TopicType, TopicUnsubscribeRequest} from './WebSocketManager';\nimport {Observable, Subject} from '@dooboostore/core';\nimport { filter } from '@dooboostore/core/message/operators';\n\nexport * from '@dooboostore/core';\n\ntype TopicObserverNextCallBack<T> = <R = any>(data: T, meta: { socket: WebSocket }) => void;\ntype TopicObserverEventCallBack = { [event: string]: <T, R = any>(data: T, meta: { socket: WebSocket }) => Promise<R> | void | any } | (<T, R = any>(event: string, data: T, meta: { socket: WebSocket }) => Promise<R> | void | any);\ntype TopicObserverErrorCallBack = <R = any>(err: any) => void;\nexport type TopicObserverCallBack<T> = { next: TopicObserverNextCallBack<T>; event?: TopicObserverEventCallBack; error?: TopicObserverErrorCallBack; complete?: () => void } | TopicObserverNextCallBack<T>;\n\nexport interface WebSocketClientConfig {\n retryConnectionCount?: number;\n retryConnectionDelay?: number;\n maxPendingMessages?: number;\n maxPendingBinaryMessages?: number;\n}\n\ntype OnUnsubscribeCallback = (type: 'server' | 'manual') => void;\nexport type Subscription = {\n closed: boolean;\n unsubscribe: () => void;\n};\n\nexport class WebSocketClient {\n private websocket: WebSocket;\n private topics = new Map<string, { observer: TopicObserverCallBack<any>; subscription: Subscription; onUnsubscribes: OnUnsubscribeCallback[]; target: string }>();\n private observer?: (data: TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest) => void;\n private pendingMessages: any[] = [];\n private pendingBinaryMessages: Array<ArrayBuffer | Blob | Uint8Array> = [];\n private isConnected = false;\n private onOpenCallback: () => void;\n private onCloseCallback: () => void;\n private _subject = new Subject<TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest>();\n // Reconnection properties\n private connectionUrl: string | URL;\n private connectionProtocols?: string | string[];\n private retryConnectionCount: number;\n private retryConnectionDelay: number;\n private currentRetryCount = 0;\n private reconnectTimeout?: number;\n private isManualClose = false;\n private isConnecting = false;\n private maxPendingMessages: number;\n private maxPendingBinaryMessages: number;\n\n constructor(connection: { url: string | URL; protocols?: string | string[] }, config?: WebSocketClientConfig);\n constructor(connection: string, config?: WebSocketClientConfig);\n constructor(connection: URL, config?: WebSocketClientConfig);\n constructor(connection: { url: string | URL; protocols?: string | string[] } | string | URL, config?: WebSocketClientConfig) {\n // Store connection info for reconnection\n if (typeof connection === 'string' || connection instanceof URL) {\n this.connectionUrl = connection;\n } else {\n this.connectionUrl = connection.url;\n this.connectionProtocols = connection.protocols;\n }\n\n // Set config with defaults\n this.retryConnectionCount = config?.retryConnectionCount ?? 0;\n this.retryConnectionDelay = config?.retryConnectionDelay ?? 1000;\n this.maxPendingMessages = config?.maxPendingMessages ?? 1000;\n this.maxPendingBinaryMessages = config?.maxPendingBinaryMessages ?? 100;\n\n this.connect();\n }\n\n private get observable() {\n return this._subject.asObservable();\n }\n\n private connect() {\n if (this.isConnecting) {\n return;\n }\n if (this.websocket && (this.websocket.readyState === WebSocket.OPEN || this.websocket.readyState === WebSocket.CONNECTING)) {\n return;\n }\n this.isConnecting = true;\n if (this.connectionProtocols) {\n this.websocket = new WebSocket(this.connectionUrl, this.connectionProtocols);\n } else {\n this.websocket = new WebSocket(this.connectionUrl);\n }\n\n this.websocket.binaryType = 'arraybuffer';\n\n this.websocket.addEventListener('open', () => {\n this.isConnecting = false;\n this.isConnected = true;\n this.currentRetryCount = 0; // Reset retry count on successful connection\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = undefined;\n }\n console.log('WebSocket connected');\n this.onOpenCallback?.();\n\n // Re-subscribe to all existing topics after reconnection\n this.topics.forEach((topicData, uuid) => {\n // closed\uB41C subscription\uC740 \uC7AC\uAD6C\uB3C5\uD558\uC9C0 \uC54A\uC74C\n if (!topicData.subscription.closed) {\n const subscribeTopic: TopicSubscribeRequest = {\n type: 'subscribe',\n uuid,\n target: topicData.target\n };\n // console.log('????')\n this.websocket.send(JSON.stringify(subscribeTopic));\n }\n });\n\n // \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uBA54\uC2DC\uC9C0 \uC804\uC1A1\n while (this.pendingMessages.length > 0) {\n const message = this.pendingMessages.shift();\n this.websocket.send(JSON.stringify(message));\n }\n\n while (this.pendingBinaryMessages.length > 0) {\n const message = this.pendingBinaryMessages.shift();\n if (message) {\n this.websocket.send(message);\n }\n }\n });\n\n this.websocket.addEventListener('close', event => {\n this.isConnecting = false;\n this.isConnected = false;\n console.log('WebSocket closed', event.code, event.reason);\n this.onCloseCallback?.();\n\n // Attempt reconnection if not manually closed\n if (!this.isManualClose) {\n this.attemptReconnect();\n }\n });\n\n this.websocket.addEventListener('error', error => {\n console.error('WebSocket error:', error);\n });\n\n this.websocket.addEventListener('message', async event => {\n const topic = await this.parseIncomingTopic(event.data);\n if (!topic) {\n return;\n }\n this._subject.next(topic);\n this.observer?.(topic);\n if (topic.uuid) {\n const topicData = this.topics.get(topic.uuid);\n if (topicData) {\n const observer = topicData.observer;\n const nextCallback = typeof observer === 'function' ? observer : observer.next;\n const errorCallback = typeof observer === 'function' ? undefined : observer.error;\n const eventCallback = typeof observer === 'function' ? undefined : observer.event;\n if ('state' in topic && topic.state === 'success') {\n await nextCallback(topic.body, { socket: this.websocket });\n } else if ('state' in topic && topic.state === 'error' && errorCallback) {\n await errorCallback(topic.body);\n } else if ('type' in topic && topic.type === 'unsubscribe') {\n topicData.subscription.closed = true;\n this.topics.delete(topic.uuid);\n topicData.onUnsubscribes.forEach(it => it('server'));\n } else if ('type' in topic && topic.type === 'event' && eventCallback) {\n /////////// event ///////////\n let eventResponse = typeof eventCallback === 'function' ? await eventCallback(topic.event, topic.body, { socket: this.websocket }) : await eventCallback[topic.event]?.(topic.body, { socket: this.websocket });\n\n if (eventResponse !== undefined && eventResponse !== null) {\n const value: TopicServerEventResponse = {\n uuid: topic.uuid,\n eventUUID: topic.eventUUID,\n type: topic.type,\n body: eventResponse\n };\n this.websocket.send(JSON.stringify(value));\n }\n }\n }\n }\n });\n }\n\n private attemptReconnect() {\n if (this.currentRetryCount >= this.retryConnectionCount) {\n console.error(`WebSocket reconnection failed after ${this.retryConnectionCount} attempts`);\n return;\n }\n if (this.reconnectTimeout) {\n return;\n }\n\n this.currentRetryCount++;\n console.log(`Attempting to reconnect... (${this.currentRetryCount}/${this.retryConnectionCount})`);\n\n this.reconnectTimeout = window.setTimeout(() => {\n this.reconnectTimeout = undefined;\n this.connect();\n // Subscribe messages are already in pendingMessages and will be sent automatically\n }, this.retryConnectionDelay);\n }\n\n private sendMessage(message: TopicRequest | TopicUnsubscribeRequest | TopicSubscribeRequest) {\n if (this.isConnected && this.websocket.readyState === WebSocket.OPEN) {\n this.websocket.send(JSON.stringify(message));\n return;\n }\n if (message.type === 'subscribe' || message.type === 'unsubscribe') {\n return;\n }\n if (this.maxPendingMessages <= 0) {\n return;\n }\n if (this.pendingMessages.length >= this.maxPendingMessages) {\n this.pendingMessages.shift();\n }\n this.pendingMessages.push(message);\n }\n\n sendBinary(data: ArrayBuffer | Blob | Uint8Array) {\n if (this.isConnected && this.websocket.readyState === WebSocket.OPEN) {\n this.websocket.send(data);\n return;\n }\n if (this.maxPendingBinaryMessages <= 0) {\n return;\n }\n if (this.pendingBinaryMessages.length >= this.maxPendingBinaryMessages) {\n this.pendingBinaryMessages.shift();\n }\n this.pendingBinaryMessages.push(data);\n }\n\n private async parseIncomingTopic(data: any): Promise<TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest | undefined> {\n if (typeof data === 'string') {\n try {\n return JSON.parse(data);\n } catch (error) {\n console.warn('Invalid WebSocket payload:', error);\n return undefined;\n }\n }\n\n if (data instanceof ArrayBuffer) {\n return this.parseBinaryTopic(data);\n }\n\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n const buffer = await data.arrayBuffer();\n return this.parseBinaryTopic(buffer);\n }\n\n return undefined;\n }\n\n private parseBinaryTopic(data: ArrayBuffer): TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest | undefined {\n if (data.byteLength < 4) {\n return undefined;\n }\n const view = new DataView(data);\n const jsonLength = view.getUint32(0, true);\n const jsonStart = 4;\n const jsonEnd = jsonStart + jsonLength;\n if (data.byteLength < jsonEnd) {\n return undefined;\n }\n\n const jsonBytes = new Uint8Array(data, jsonStart, jsonLength);\n let meta: any;\n try {\n const decoder = new TextDecoder();\n meta = JSON.parse(decoder.decode(jsonBytes));\n } catch (error) {\n console.warn('Invalid WebSocket binary payload:', error);\n return undefined;\n }\n\n const filesMeta = Array.isArray(meta.files) ? meta.files : [];\n const fileMap = new Map<string, any>();\n filesMeta.forEach((file: any) => {\n if (!file || typeof file.id !== 'string' || typeof file.size !== 'number' || typeof file.offset !== 'number') {\n return;\n }\n const start = jsonEnd + file.offset;\n const end = start + file.size;\n if (start < jsonEnd || end > data.byteLength) {\n return;\n }\n const slice = data.slice(start, end);\n const mime = file.mime || 'application/octet-stream';\n let fileValue: any;\n if (typeof File !== 'undefined') {\n fileValue = new File([slice], file.name || 'file', { type: mime });\n } else {\n fileValue = { name: file.name || 'file', mime, size: file.size, buffer: slice };\n }\n fileMap.set(file.id, fileValue);\n });\n\n const replaceFileRefs = (value: any): any => {\n if (value && typeof value === 'object' && '$file' in value && typeof value.$file === 'string') {\n const file = fileMap.get(value.$file);\n if (file) {\n return file;\n }\n }\n if (Array.isArray(value)) {\n return value.map(item => replaceFileRefs(item));\n }\n if (value && typeof value === 'object') {\n const result: Record<string, any> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFileRefs(value[key]);\n });\n return result;\n }\n return value;\n };\n\n meta.body = replaceFileRefs(meta.body);\n return meta as TopicResponse | TopicServerEventRequest | TopicServerEventUnSubscribeRequest;\n }\n\n private isBinaryPayload(value: any) {\n if (!value) {\n return false;\n }\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return true;\n }\n if (typeof Uint8Array !== 'undefined' && value instanceof Uint8Array) {\n return true;\n }\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n return true;\n }\n if (value && typeof value === 'object' && 'buffer' in value) {\n const bufferValue = (value as any).buffer;\n return this.isBinaryPayload(bufferValue);\n }\n return false;\n }\n\n private hasBinaryPayload(value: any): boolean {\n if (this.isBinaryPayload(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.some(item => this.hasBinaryPayload(item));\n }\n if (value && typeof value === 'object') {\n return Object.keys(value).some(key => this.hasBinaryPayload(value[key]));\n }\n return false;\n }\n\n private async buildBinaryMessage(body: any, meta: { type?: TopicType; uuid: string; requestUUID: string }) {\n const fileRefs = new Map<any, string>();\n const fileEntries: Array<{ id: string; name: string; mime: string; buffer: Promise<ArrayBuffer | SharedArrayBuffer> }> = [];\n let fileIndex = 0;\n\n const registerFile = (value: any) => {\n const existing = fileRefs.get(value);\n if (existing) {\n return existing;\n }\n const id = `f${++fileIndex}`;\n fileRefs.set(value, id);\n\n let name = 'file';\n let mime = 'application/octet-stream';\n let buffer: Promise<ArrayBuffer | SharedArrayBuffer>;\n\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n const fileLike = value as File | Blob;\n if ('name' in fileLike && typeof (fileLike as File).name === 'string') {\n name = (fileLike as File).name || name;\n }\n mime = fileLike.type || mime;\n buffer = fileLike.arrayBuffer();\n } else if (value && typeof value === 'object' && 'buffer' in value) {\n const fileLike = value as any;\n if (typeof fileLike.name === 'string') {\n name = fileLike.name || name;\n }\n if (typeof fileLike.mime === 'string') {\n mime = fileLike.mime || mime;\n }\n const innerBuffer = fileLike.buffer;\n if (typeof Blob !== 'undefined' && innerBuffer instanceof Blob) {\n buffer = innerBuffer.arrayBuffer();\n } else if (typeof Uint8Array !== 'undefined' && innerBuffer instanceof Uint8Array) {\n const sliced = innerBuffer.buffer.slice(innerBuffer.byteOffset, innerBuffer.byteOffset + innerBuffer.byteLength);\n buffer = Promise.resolve(sliced instanceof ArrayBuffer ? sliced : new Uint8Array(sliced).buffer);\n } else if (typeof ArrayBuffer !== 'undefined' && innerBuffer instanceof ArrayBuffer) {\n buffer = Promise.resolve(innerBuffer as ArrayBuffer);\n } else {\n buffer = Promise.resolve(new ArrayBuffer(0));\n }\n } else if (typeof Uint8Array !== 'undefined' && value instanceof Uint8Array) {\n const view = value as Uint8Array;\n const sliced = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);\n buffer = Promise.resolve(sliced instanceof ArrayBuffer ? sliced : new Uint8Array(sliced).buffer);\n } else if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n buffer = Promise.resolve(value as ArrayBuffer);\n } else {\n buffer = Promise.resolve(new ArrayBuffer(0));\n }\n\n fileEntries.push({ id, name, mime, buffer });\n return id;\n };\n\n const replaceFiles = (value: any): any => {\n if (this.isBinaryPayload(value)) {\n const id = registerFile(value);\n return { $file: id };\n }\n if (Array.isArray(value)) {\n return value.map(item => replaceFiles(item));\n }\n if (value && typeof value === 'object') {\n const result: Record<string, any> = {};\n Object.keys(value).forEach(key => {\n result[key] = replaceFiles(value[key]);\n });\n return result;\n }\n return value;\n };\n\n const payload = replaceFiles(body);\n const buffers = await Promise.all(fileEntries.map(entry => entry.buffer));\n\n let offset = 0;\n const files = fileEntries.map((entry, index) => {\n const size = buffers[index].byteLength;\n const fileMeta = {\n id: entry.id,\n name: entry.name,\n mime: entry.mime,\n size,\n offset\n };\n offset += size;\n return fileMeta;\n });\n\n const json = JSON.stringify({\n type: meta.type,\n uuid: meta.uuid,\n requestUUID: meta.requestUUID,\n body: payload,\n files\n });\n\n const encoder = new TextEncoder();\n const jsonBytes = encoder.encode(json);\n const header = new Uint8Array(4);\n new DataView(header.buffer).setUint32(0, jsonBytes.byteLength, true);\n\n const totalSize = header.byteLength + jsonBytes.byteLength + offset;\n const combined = new Uint8Array(totalSize);\n combined.set(header, 0);\n combined.set(jsonBytes, header.byteLength);\n\n let cursor = header.byteLength + jsonBytes.byteLength;\n buffers.forEach(buffer => {\n const view = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : new Uint8Array(buffer);\n combined.set(view, cursor);\n cursor += buffer.byteLength;\n });\n\n return combined.buffer;\n }\n\n subject(target: string, option?: { type?: TopicType; subScribeBody?: any; observer?: TopicObserverCallBack<any>; onUnsubscribe?: OnUnsubscribeCallback }) {\n const self = this;\n const uuid = RandomUtils.uuid4();\n const onUnsubscribes: OnUnsubscribeCallback[] = [];\n if (option?.onUnsubscribe) {\n onUnsubscribes.push(option.onUnsubscribe);\n }\n if (option?.observer && typeof option.observer !== 'function' && option.observer.complete) {\n onUnsubscribes.push(() => (option.observer as any).complete());\n }\n const topicSubject = new Subject<any>();\n onUnsubscribes.push(() => topicSubject.complete());\n\n let isClosed = false;\n let activeSubscription: Subscription | undefined;\n\n const unsubscribeLogic = () => {\n if (isClosed) return;\n const unSubscribeTopic: TopicUnsubscribeRequest = { type: 'unsubscribe', uuid };\n self.sendMessage(unSubscribeTopic);\n isClosed = true;\n self.topics.delete(uuid);\n onUnsubscribes.forEach(it => it('manual'));\n if (activeSubscription) {\n activeSubscription.closed = true;\n }\n };\n\n const doSubscribe = <T>(observer?: TopicObserverCallBack<T>) => {\n const subscription: Subscription = {\n closed: isClosed,\n unsubscribe: unsubscribeLogic\n };\n\n const wrappedObserver: TopicObserverCallBack<T> = {\n next: (data, meta) => {\n topicSubject.next(data);\n if (observer) {\n return typeof observer === 'function' ? observer(data, meta) : observer.next(data, meta);\n }\n },\n error: err => {\n topicSubject.error(err);\n if (observer && typeof observer !== 'function' && observer.error) {\n observer.error(err);\n }\n },\n event: observer && typeof observer !== 'function' ? observer.event : undefined\n };\n\n self.topics.set(uuid, { observer: wrappedObserver, target, subscription, onUnsubscribes });\n const subscribeTopic: TopicSubscribeRequest = { type: 'subscribe', uuid, target: target, body: option?.subScribeBody };\n\n self.sendMessage(subscribeTopic);\n // console.log('----------')\n activeSubscription = subscription;\n return subscription;\n };\n\n if (option?.observer) {\n doSubscribe(option.observer);\n }\n\n return {\n get closed() {\n return isClosed;\n },\n unsubscribe: unsubscribeLogic,\n get observable() {\n return new Observable<any>(subscriber => {\n if (!activeSubscription && !isClosed) {\n doSubscribe();\n }\n return topicSubject.subscribe({\n next: value => subscriber.next(value),\n error: err => subscriber.error(err),\n complete: () => subscriber.complete()\n });\n });\n },\n send: (body?: any) => {\n if (!activeSubscription && !self.topics.has(uuid) && !isClosed) {\n doSubscribe();\n }\n const requestUUID = RandomUtils.uuid4();\n if (self.hasBinaryPayload(body)) {\n self.buildBinaryMessage(body, { type: option?.type, uuid, requestUUID }).then(buffer => self.sendBinary(buffer));\n } else {\n const value: TopicRequest = { type: option?.type, uuid, requestUUID, body: body };\n self.sendMessage(value);\n }\n return topicSubject.pipe(filter(data => data && data.requestUUID === requestUUID));\n },\n onUnsubscribe: (callback: OnUnsubscribeCallback) => {\n onUnsubscribes.push(callback);\n }\n };\n }\n\n onOpen(callback: () => void) {\n this.onOpenCallback = callback;\n }\n\n onClose(callback: () => void) {\n this.onCloseCallback = callback;\n }\n\n subscribe<T = any>(observer: (data: TopicResponse<T> | TopicServerEventRequest<T>) => void) {\n this.observer = observer;\n }\n\n close() {\n this.isManualClose = true;\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = undefined;\n }\n this.pendingMessages = [];\n this.pendingBinaryMessages = [];\n this.isConnecting = false;\n this.topics.forEach(topicData => {\n topicData.subscription.closed = true;\n topicData.onUnsubscribes.forEach(it => it('manual'));\n });\n this.topics.clear();\n this.websocket.close();\n }\n\n reconnect() {\n // \uAE30\uC874 \uC5F0\uACB0 \uC885\uB8CC\n this.isManualClose = true;\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n }\n\n // close \uC774\uBCA4\uD2B8 \uD6C4\uC5D0 \uC7AC\uC5F0\uACB0\uD558\uB3C4\uB85D \uC124\uC815\n const reconnectAfterClose = () => {\n console.log('close websocket');\n this.isManualClose = false;\n this.currentRetryCount = 0;\n this.connect();\n };\n\n // \uC774\uBBF8 \uB2EB\uD600\uC788\uC73C\uBA74 \uBC14\uB85C \uC7AC\uC5F0\uACB0\n if (this.websocket.readyState === WebSocket.CLOSED || this.websocket.readyState === WebSocket.CLOSING) {\n reconnectAfterClose();\n } else {\n // \uC5F0\uACB0\uC774 \uB2EB\uD790 \uB54C\uAE4C\uC9C0 \uAE30\uB2E4\uB838\uB2E4\uAC00 \uC7AC\uC5F0\uACB0\n this.websocket.addEventListener('close', reconnectAfterClose, { once: true });\n this.websocket.close();\n }\n }\n\n getReadyState(): number {\n return this.websocket.readyState;\n }\n\n isConnectionOpen(): boolean {\n return this.isConnected && this.websocket.readyState === WebSocket.OPEN;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_core"]
7
7
  }
@@ -69,7 +69,9 @@ let WebSocketManager = class WebSocketManager2 {
69
69
  constructor(intentManager, routerManager) {
70
70
  this.intentManager = intentManager;
71
71
  this.routerManager = routerManager;
72
- this.clients = /* @__PURE__ */ new Map();
72
+ this.connections = /* @__PURE__ */ new Map();
73
+ this.registrations = /* @__PURE__ */ new Map();
74
+ this.targets = /* @__PURE__ */ new Map();
73
75
  this.eventSubscriptions = /* @__PURE__ */ new Map();
74
76
  this.subject = new import_core2.Subject();
75
77
  }
@@ -77,61 +79,76 @@ let WebSocketManager = class WebSocketManager2 {
77
79
  return this.subject.asObservable();
78
80
  }
79
81
  connect(wsSet) {
80
- this.clients.set(wsSet, []);
82
+ this.connections.set(wsSet, /* @__PURE__ */ new Set());
81
83
  console.log("WebSocket connected:", wsSet.request.url);
82
84
  }
83
85
  close(wsSet) {
84
86
  this.removeAllClientsByWebSocketSet(wsSet);
85
- this.clients.delete(wsSet);
87
+ this.connections.delete(wsSet);
86
88
  console.log("WebSocket disconnected:", wsSet.request.url);
87
89
  }
88
90
  setClientTopic(wsSet, uuid, target, subscribeBody) {
89
- const clientTopics = this.clients.get(wsSet);
90
- if (clientTopics && !clientTopics.find((it) => it.uuid === uuid)) {
91
- clientTopics.push({ uuid, target, subscribeBody });
92
- this.clients.set(wsSet, clientTopics);
93
- } else if (clientTopics) {
94
- throw { message: "Already subscribed topic" };
91
+ const uuidSet = this.connections.get(wsSet);
92
+ if (!uuidSet) {
93
+ return;
94
+ }
95
+ if (this.registrations.has(uuid)) {
96
+ throw new Error("Already subscribed topic");
97
+ }
98
+ this.registrations.set(uuid, { uuid, target, subscribeBody, webSocketSet: wsSet });
99
+ uuidSet.add(uuid);
100
+ if (!this.targets.get(target)) {
101
+ this.targets.set(target, /* @__PURE__ */ new Set());
95
102
  }
103
+ this.targets.get(target)?.add(uuid);
96
104
  }
97
105
  findAllClientsByTarget(target) {
106
+ const uuids = this.targets.get(target);
107
+ if (!uuids) {
108
+ return [];
109
+ }
98
110
  const results = [];
99
- for (const [wsSet, topics] of Array.from(this.clients.entries())) {
100
- const find = topics.find((it) => it.target === target);
101
- if (find) {
102
- results.push({ ...find, webSocketSet: wsSet });
111
+ uuids.forEach((uuid) => {
112
+ const reg = this.registrations.get(uuid);
113
+ if (reg) {
114
+ results.push({ ...reg });
103
115
  }
104
- }
116
+ });
105
117
  return results;
106
118
  }
107
119
  findClientsByTarget(target) {
108
- for (const [wsSet, topics] of Array.from(this.clients.entries())) {
109
- const find = topics.find((it) => it.target === target);
110
- if (find) {
111
- return { ...find, webSocketSet: wsSet };
120
+ const uuids = this.targets.get(target);
121
+ if (!uuids) {
122
+ return void 0;
123
+ }
124
+ for (const uuid of Array.from(uuids)) {
125
+ const reg = this.registrations.get(uuid);
126
+ if (reg) {
127
+ return { ...reg };
112
128
  }
113
129
  }
130
+ return void 0;
114
131
  }
115
132
  removeClientByUUID(uuid) {
116
- for (const [wsSet, topics] of Array.from(this.clients.entries())) {
117
- const findIndex = topics.findIndex((it) => it.uuid === uuid);
118
- if (findIndex >= 0) {
119
- topics.splice(findIndex, 1);
120
- this.clients.set(wsSet, topics);
121
- this.eventSubscriptions.delete(uuid);
122
- return true;
133
+ const reg = this.registrations.get(uuid);
134
+ if (!reg) {
135
+ return false;
136
+ }
137
+ this.registrations.delete(uuid);
138
+ this.connections.get(reg.webSocketSet)?.delete(uuid);
139
+ const targetSet = this.targets.get(reg.target);
140
+ if (targetSet) {
141
+ targetSet.delete(uuid);
142
+ if (targetSet.size <= 0) {
143
+ this.targets.delete(reg.target);
123
144
  }
124
145
  }
125
- return false;
146
+ this.eventSubscriptions.delete(uuid);
147
+ return true;
126
148
  }
127
149
  findClientByUUID(uuid) {
128
- for (const [wsSet, topics] of Array.from(this.clients.entries())) {
129
- const find = topics.find((it) => it.uuid === uuid);
130
- if (find) {
131
- return { ...find, webSocketSet: wsSet };
132
- }
133
- }
134
- return void 0;
150
+ const reg = this.registrations.get(uuid);
151
+ return reg ? { ...reg } : void 0;
135
152
  }
136
153
  sendDataByUUID({ uuid, body }) {
137
154
  const client = this.findClientByUUID(uuid);
@@ -296,7 +313,7 @@ let WebSocketManager = class WebSocketManager2 {
296
313
  }
297
314
  }
298
315
  getOpenClients() {
299
- return Array.from(this.clients.keys()).filter((it) => it.socket.readyState === import_ws.WebSocket.OPEN);
316
+ return Array.from(this.connections.keys()).filter((it) => it.socket.readyState === import_ws.WebSocket.OPEN);
300
317
  }
301
318
  isBinaryPayload(value) {
302
319
  if (!value) {
@@ -624,14 +641,25 @@ let WebSocketManager = class WebSocketManager2 {
624
641
  }
625
642
  }
626
643
  removeAllClientsByWebSocketSet(wsSet) {
627
- const topics = this.clients.get(wsSet);
628
- if (!topics) {
644
+ const uuidSet = this.connections.get(wsSet);
645
+ if (!uuidSet) {
629
646
  return;
630
647
  }
631
- for (const topic of topics) {
632
- this.eventSubscriptions.delete(topic.uuid);
633
- }
634
- this.clients.set(wsSet, []);
648
+ uuidSet.forEach((uuid) => {
649
+ const reg = this.registrations.get(uuid);
650
+ if (reg) {
651
+ this.registrations.delete(uuid);
652
+ const targetSet = this.targets.get(reg.target);
653
+ if (targetSet) {
654
+ targetSet.delete(uuid);
655
+ if (targetSet.size <= 0) {
656
+ this.targets.delete(reg.target);
657
+ }
658
+ }
659
+ }
660
+ this.eventSubscriptions.delete(uuid);
661
+ });
662
+ uuidSet.clear();
635
663
  }
636
664
  };
637
665
  WebSocketManager = __decorate([