@isdk/ai-tool 0.7.0 → 0.8.0

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 (359) hide show
  1. package/dist/chunk-4FKBOPZI.mjs +1 -0
  2. package/dist/{chunk-VIG2GB47.mjs → chunk-TGTHY57V.mjs} +1 -1
  3. package/dist/funcs.d.mts +1 -2
  4. package/dist/funcs.d.ts +1 -2
  5. package/dist/funcs.js +1 -1
  6. package/dist/funcs.mjs +1 -1
  7. package/dist/{index-BCco-g_I.d.mts → index-BLW3R7VS.d.mts} +114 -69
  8. package/dist/{index-BCco-g_I.d.ts → index-BLW3R7VS.d.ts} +114 -69
  9. package/dist/index.d.mts +101 -38
  10. package/dist/index.d.ts +101 -38
  11. package/dist/index.js +1 -1
  12. package/dist/index.mjs +1 -1
  13. package/dist/test/util.js +1 -1
  14. package/dist/test/util.mjs +1 -1
  15. package/docs/api/{namespaces → @isdk/namespaces}/EventStates/README.md +2 -2
  16. package/docs/api/{namespaces → @isdk/namespaces}/EventStates/variables/ABORT.md +2 -2
  17. package/docs/api/{namespaces → @isdk/namespaces}/EventStates/variables/CONTINUE.md +2 -2
  18. package/docs/api/{namespaces → @isdk/namespaces}/EventStates/variables/DONE.md +2 -2
  19. package/docs/api/{namespaces → @isdk/namespaces}/EventStates/variables/STOPPED.md +2 -2
  20. package/docs/api/@isdk/namespaces/uuidv5/README.md +12 -0
  21. package/docs/api/{namespaces → @isdk/namespaces}/uuidv5/variables/DNS.md +2 -2
  22. package/docs/api/{namespaces → @isdk/namespaces}/uuidv5/variables/URL.md +2 -2
  23. package/docs/api/_media/pubsub.md +427 -105
  24. package/docs/api/_media/server_client_tools.md +5 -3
  25. package/docs/api/_media/toolFunc.md +3 -1
  26. package/docs/api/classes/AbortError.md +8 -8
  27. package/docs/api/classes/AlreadyExistsError.md +8 -8
  28. package/docs/api/classes/BaseError.md +14 -14
  29. package/docs/api/classes/BinarySemaphore.md +39 -39
  30. package/docs/api/classes/CancelableAbility.md +43 -39
  31. package/docs/api/classes/ClientToolTransport.md +22 -22
  32. package/docs/api/classes/ClientTools.md +182 -154
  33. package/docs/api/classes/CommonError.md +12 -12
  34. package/docs/api/classes/ConfigFile.md +6 -6
  35. package/docs/api/classes/EnvPromptTemplate.md +14 -14
  36. package/docs/api/classes/EventClient.md +258 -201
  37. package/docs/api/classes/EventEmitter.md +14 -14
  38. package/docs/api/classes/EventServer.md +220 -237
  39. package/docs/api/classes/EventToolFunc.md +144 -116
  40. package/docs/api/classes/FStringPromptTemplate.md +14 -14
  41. package/docs/api/classes/FewShotPromptTemplate.md +30 -26
  42. package/docs/api/classes/GolangPromptTemplate.md +13 -13
  43. package/docs/api/classes/HttpClientToolTransport.md +23 -23
  44. package/docs/api/classes/HttpServerToolTransport.md +40 -27
  45. package/docs/api/classes/IntSet.md +21 -21
  46. package/docs/api/classes/LRUCache.md +18 -18
  47. package/docs/api/classes/NotFoundError.md +8 -8
  48. package/docs/api/classes/NotImplementationError.md +8 -8
  49. package/docs/api/classes/PromptExampleSelector.md +17 -15
  50. package/docs/api/classes/PromptTemplate.md +15 -15
  51. package/docs/api/classes/ReadableStreamError.md +12 -12
  52. package/docs/api/classes/ResClientTools.md +658 -143
  53. package/docs/api/classes/ResServerTools.md +643 -133
  54. package/docs/api/classes/RpcMethodsClientTool.md +3303 -0
  55. package/docs/api/classes/RpcMethodsServerTool.md +3248 -0
  56. package/docs/api/classes/SSEChannel.md +142 -52
  57. package/docs/api/classes/Semaphore.md +40 -40
  58. package/docs/api/classes/ServerToolTransport.md +32 -27
  59. package/docs/api/classes/ServerTools.md +167 -139
  60. package/docs/api/classes/SignalGate.md +19 -17
  61. package/docs/api/classes/SseClientPubSubTransport.md +38 -10
  62. package/docs/api/classes/SseServerPubSubTransport.md +115 -42
  63. package/docs/api/classes/TaskAbortController.md +13 -13
  64. package/docs/api/classes/ToolFunc.md +157 -129
  65. package/docs/api/classes/ToolTransport.md +13 -13
  66. package/docs/api/classes/YamlTypeBaseObject.md +5 -5
  67. package/docs/api/enumerations/AsyncFeatureBits.md +4 -4
  68. package/docs/api/enumerations/AsyncFeatures.md +4 -4
  69. package/docs/api/enumerations/HashAlgorithm.md +12 -12
  70. package/docs/api/functions/AIArgProcessor.md +2 -2
  71. package/docs/api/functions/AIStream.md +8 -4
  72. package/docs/api/functions/ChoiceArgProcessor.md +2 -2
  73. package/docs/api/functions/DefaultDateFormat.md +2 -2
  74. package/docs/api/functions/ObjectArgsToArgsInfo.md +1 -1
  75. package/docs/api/functions/RateLimit.md +2 -2
  76. package/docs/api/functions/TemplateArgProcessor.md +2 -2
  77. package/docs/api/functions/addDate.md +7 -3
  78. package/docs/api/functions/assignDirs.md +1 -1
  79. package/docs/api/functions/beforeShutdown.md +1 -1
  80. package/docs/api/functions/calcPerplexity.md +2 -2
  81. package/docs/api/functions/calcPerplexitySimple.md +1 -1
  82. package/docs/api/functions/canonicalize.md +1 -1
  83. package/docs/api/functions/completeSentences.md +1 -1
  84. package/docs/api/functions/concatText.md +1 -1
  85. package/docs/api/functions/countLLMTokens.md +1 -1
  86. package/docs/api/functions/countRegexMatches.md +1 -1
  87. package/docs/api/functions/createAbilityInjector.md +16 -8
  88. package/docs/api/functions/createCallbacksTransformer.md +7 -3
  89. package/docs/api/functions/createEmptyReadableStream.md +1 -1
  90. package/docs/api/functions/createEndWithRepetitionDetector.md +2 -2
  91. package/docs/api/functions/createError.md +1 -1
  92. package/docs/api/functions/createEventStreamTransformer.md +8 -4
  93. package/docs/api/functions/createHfValueFunc.md +1 -1
  94. package/docs/api/functions/createLRUCache.md +2 -2
  95. package/docs/api/functions/createYamlObjectTag.md +1 -1
  96. package/docs/api/functions/dateToText.md +1 -1
  97. package/docs/api/functions/decodeCharset.md +2 -2
  98. package/docs/api/functions/defaultsWithConcat.md +1 -1
  99. package/docs/api/functions/detectCharset.md +2 -2
  100. package/docs/api/functions/encodeLLMTokens.md +1 -1
  101. package/docs/api/functions/ensureQuoted.md +1 -1
  102. package/docs/api/functions/eventable.md +6 -8
  103. package/docs/api/functions/expandConfig.md +2 -2
  104. package/docs/api/functions/expandObjEnv.md +1 -1
  105. package/docs/api/functions/expandPath.md +2 -2
  106. package/docs/api/functions/expandPathInObject.md +2 -2
  107. package/docs/api/functions/expandPaths.md +2 -2
  108. package/docs/api/functions/fileIsExists.md +1 -1
  109. package/docs/api/functions/filterValidFnScope.md +2 -2
  110. package/docs/api/functions/findIndexNonEmptyFrom.md +1 -1
  111. package/docs/api/functions/findPort.md +1 -1
  112. package/docs/api/functions/formatISO.md +1 -1
  113. package/docs/api/functions/formatTextWithSpace.md +2 -2
  114. package/docs/api/functions/funcGetMeta.md +1 -1
  115. package/docs/api/functions/funcWithMeta.md +2 -2
  116. package/docs/api/functions/genUrlParamsStr.md +8 -2
  117. package/docs/api/functions/getAllEnumKeys.md +4 -2
  118. package/docs/api/functions/getConfigFileNames.md +2 -2
  119. package/docs/api/functions/getConfigs.md +2 -2
  120. package/docs/api/functions/getFileMetaInfo.md +1 -1
  121. package/docs/api/functions/getHashAlgoBySize.md +1 -1
  122. package/docs/api/functions/getKeysPath.md +4 -2
  123. package/docs/api/functions/getLLMTokenizer.md +1 -1
  124. package/docs/api/functions/getMultiLevelExtname.md +1 -1
  125. package/docs/api/functions/getPackageDir.md +1 -1
  126. package/docs/api/functions/getRealFilepath.md +1 -1
  127. package/docs/api/functions/getResponseErrorReadableStream.md +2 -2
  128. package/docs/api/functions/getXDGConfigs.md +1 -1
  129. package/docs/api/functions/hasDirectoryIn.md +2 -2
  130. package/docs/api/functions/hash.md +1 -1
  131. package/docs/api/functions/hashFile.md +2 -2
  132. package/docs/api/functions/hashObject.md +2 -2
  133. package/docs/api/functions/hashStream.md +1 -1
  134. package/docs/api/functions/initShutdown.md +1 -1
  135. package/docs/api/functions/isLangUsingSpaces.md +1 -1
  136. package/docs/api/functions/isListItemString.md +1 -1
  137. package/docs/api/functions/isModelNameMatched.md +2 -2
  138. package/docs/api/functions/isPunctuationChar.md +1 -1
  139. package/docs/api/functions/isQuoted.md +1 -1
  140. package/docs/api/functions/isRegExp.md +1 -1
  141. package/docs/api/functions/isSameString.md +1 -1
  142. package/docs/api/functions/isSectionString.md +2 -2
  143. package/docs/api/functions/isSentenceEnding.md +1 -1
  144. package/docs/api/functions/isSepLineString.md +1 -1
  145. package/docs/api/functions/isStrWrapped.md +1 -1
  146. package/docs/api/functions/isSubdirectory.md +1 -1
  147. package/docs/api/functions/isTitleString.md +2 -2
  148. package/docs/api/functions/isWebStream.md +1 -1
  149. package/docs/api/functions/joinSplitWords.md +1 -1
  150. package/docs/api/functions/jsonFilterToWhere.md +2 -2
  151. package/docs/api/functions/jsonToMarkdownStr.md +2 -2
  152. package/docs/api/functions/loadAIConfig.md +1 -1
  153. package/docs/api/functions/loadConfig.md +1 -1
  154. package/docs/api/functions/loadConfigFile.md +1 -1
  155. package/docs/api/functions/loadFileFromPaths.md +2 -2
  156. package/docs/api/functions/loadTextFromPaths.md +3 -3
  157. package/docs/api/functions/lrucache.md +1 -1
  158. package/docs/api/functions/matchUrlProtocol.md +1 -1
  159. package/docs/api/functions/memoize.md +5 -3
  160. package/docs/api/functions/mergeArray.md +1 -1
  161. package/docs/api/functions/messagesToText.md +1 -1
  162. package/docs/api/functions/nanoid.md +45 -0
  163. package/docs/api/functions/normalizePath.md +1 -1
  164. package/docs/api/functions/paramsSizeToScaleStr.md +1 -1
  165. package/docs/api/functions/parseCommand.md +3 -3
  166. package/docs/api/functions/parseDateFormat.md +7 -3
  167. package/docs/api/functions/parseISO.md +7 -3
  168. package/docs/api/functions/parseJsJson.md +2 -2
  169. package/docs/api/functions/parseJsJsonSimpleSync.md +2 -2
  170. package/docs/api/functions/parseObjectArgInfo.md +2 -2
  171. package/docs/api/functions/parseObjectArgumentInfos.md +2 -2
  172. package/docs/api/functions/parseObjectArguments.md +2 -2
  173. package/docs/api/functions/parseObjectArgumentsAsArgInfos.md +2 -2
  174. package/docs/api/functions/parseYaml.md +1 -1
  175. package/docs/api/functions/pruneSubdirectories.md +1 -1
  176. package/docs/api/functions/pruneSubdirectoriesInPlace.md +1 -1
  177. package/docs/api/functions/quoteStr.md +1 -1
  178. package/docs/api/functions/readFilenamesRecursiveSync.md +2 -2
  179. package/docs/api/functions/readTextFileChunks.md +2 -2
  180. package/docs/api/functions/readTextFileChunksEx.md +2 -2
  181. package/docs/api/functions/readableFromAsyncIterable.md +4 -2
  182. package/docs/api/functions/registerCoreTools.md +1 -1
  183. package/docs/api/functions/removeMarkdownBold.md +2 -2
  184. package/docs/api/functions/removeMarkdownBoldAndItalic.md +2 -2
  185. package/docs/api/functions/removeMarkdownItalic.md +2 -2
  186. package/docs/api/functions/replaceWithPlaceholder.md +2 -2
  187. package/docs/api/functions/restoreFromPlacehoders.md +2 -2
  188. package/docs/api/functions/sanitizeFilename.md +1 -1
  189. package/docs/api/functions/sanitizeFilepath.md +1 -1
  190. package/docs/api/functions/saveConfigFile.md +1 -1
  191. package/docs/api/functions/scaleStrToParamsSize.md +1 -1
  192. package/docs/api/functions/shutdown.md +1 -1
  193. package/docs/api/functions/simplifyObjectArguments.md +1 -1
  194. package/docs/api/functions/sleep.md +1 -1
  195. package/docs/api/functions/sortedValues.md +4 -2
  196. package/docs/api/functions/splitChunks.md +2 -2
  197. package/docs/api/functions/splitParagraph.md +2 -2
  198. package/docs/api/functions/splitSentence.md +1 -1
  199. package/docs/api/functions/splitWords.md +1 -1
  200. package/docs/api/functions/stringifyYaml.md +1 -1
  201. package/docs/api/functions/stripConsoleColor.md +1 -1
  202. package/docs/api/functions/textToDate.md +1 -1
  203. package/docs/api/functions/throwError.md +1 -1
  204. package/docs/api/functions/toDate.md +7 -3
  205. package/docs/api/functions/toDateTime.md +1 -1
  206. package/docs/api/functions/trimStartOfStreamHelper.md +3 -3
  207. package/docs/api/functions/truncTo.md +1 -1
  208. package/docs/api/functions/truncateByToken.md +2 -2
  209. package/docs/api/functions/truncateToTokenLimit.md +2 -2
  210. package/docs/api/functions/truncateToTokenLimitEx.md +2 -2
  211. package/docs/api/functions/uuid.md +15 -6
  212. package/docs/api/functions/uuidStringify.md +1 -1
  213. package/docs/api/functions/uuidv1.md +5 -3
  214. package/docs/api/functions/uuidv4.md +5 -3
  215. package/docs/api/functions/uuidv5.md +5 -3
  216. package/docs/api/functions/uuidv6.md +61 -0
  217. package/docs/api/functions/uuidv7.md +61 -0
  218. package/docs/api/functions/wrapEventEmitter.md +1 -1
  219. package/docs/api/functions/xxhash.md +1 -1
  220. package/docs/api/functions/xxhash32.md +1 -1
  221. package/docs/api/functions/xxhash64.md +1 -1
  222. package/docs/api/functions/xxhashAsStr.md +1 -1
  223. package/docs/api/functions/yieldExec.md +1 -1
  224. package/docs/api/globals.md +17 -6
  225. package/docs/api/interfaces/AIChatAssistantMessageParam.md +12 -12
  226. package/docs/api/interfaces/AIChatContentPartImage.md +3 -3
  227. package/docs/api/interfaces/AIChatContentPartText.md +3 -3
  228. package/docs/api/interfaces/AIChatMessageParamBase.md +7 -7
  229. package/docs/api/interfaces/AIChatMessageToolCall.md +4 -4
  230. package/docs/api/interfaces/AIChatSystemMessageParam.md +9 -9
  231. package/docs/api/interfaces/AIChatToolChoiceFuncObject.md +3 -3
  232. package/docs/api/interfaces/AIChatToolChoiceObject.md +2 -2
  233. package/docs/api/interfaces/AIChatToolFunc.md +5 -5
  234. package/docs/api/interfaces/AIChatToolFuncParam.md +3 -3
  235. package/docs/api/interfaces/AIChatToolMessageParam.md +10 -10
  236. package/docs/api/interfaces/AIChatToolParam.md +2 -2
  237. package/docs/api/interfaces/AIChatToolTypeObject.md +2 -2
  238. package/docs/api/interfaces/AIChatUserMessageParam.md +13 -13
  239. package/docs/api/interfaces/AIChoiceConfig.md +8 -8
  240. package/docs/api/interfaces/AIResult.md +12 -8
  241. package/docs/api/interfaces/AIStreamParser.md +8 -6
  242. package/docs/api/interfaces/AIStreamParserOptions.md +2 -2
  243. package/docs/api/interfaces/BaseFunc.md +17 -17
  244. package/docs/api/interfaces/BaseFuncItem.md +15 -15
  245. package/docs/api/interfaces/BinarySemaphoreAcquireOptions.md +2 -2
  246. package/docs/api/interfaces/BinarySemaphoreOptions.md +5 -5
  247. package/docs/api/interfaces/BinarySemaphoreReleaseOptions.md +2 -2
  248. package/docs/api/interfaces/BinarySemaphoreReleaserFunc.md +3 -3
  249. package/docs/api/interfaces/CancelableAbilityOptions.md +4 -4
  250. package/docs/api/interfaces/ClientFuncItem.md +21 -25
  251. package/docs/api/interfaces/EventClientFuncParams.md +5 -5
  252. package/docs/api/interfaces/EventServerFuncParams.md +14 -6
  253. package/docs/api/interfaces/FewShotPromptTemplateOptions.md +9 -7
  254. package/docs/api/interfaces/FuncItem.md +18 -18
  255. package/docs/api/interfaces/FuncParam.md +5 -5
  256. package/docs/api/interfaces/FuncParams.md +1 -1
  257. package/docs/api/interfaces/Funcs.md +1 -1
  258. package/docs/api/interfaces/HashAlgoParams.md +4 -4
  259. package/docs/api/interfaces/IClientToolTransport.md +9 -9
  260. package/docs/api/interfaces/IFileMetaInfo.md +8 -8
  261. package/docs/api/interfaces/IPubSubClientTransport.md +31 -7
  262. package/docs/api/interfaces/IPubSubServerTransport.md +92 -47
  263. package/docs/api/interfaces/IReadTextFileChunksOptions.md +13 -13
  264. package/docs/api/interfaces/IServerToolTransport.md +19 -14
  265. package/docs/api/interfaces/IToolTransport.md +6 -6
  266. package/docs/api/interfaces/ITruncateToTokenLimitOptions.md +11 -11
  267. package/docs/api/interfaces/JsonFilter.md +1 -1
  268. package/docs/api/interfaces/ParseObjectArgumentOptions.md +11 -11
  269. package/docs/api/interfaces/ProbabilityItem.md +4 -4
  270. package/docs/api/interfaces/PromptExampleSelectorOptions.md +3 -3
  271. package/docs/api/interfaces/PubSubClientStream.md +26 -14
  272. package/docs/api/interfaces/PubSubServerSession.md +8 -8
  273. package/docs/api/interfaces/RemoteFuncItem.md +21 -25
  274. package/docs/api/interfaces/ReplacePlacehoderOptions.md +5 -5
  275. package/docs/api/interfaces/ResClientFuncParams.md +5 -5
  276. package/docs/api/interfaces/ResServerFuncParams.md +14 -10
  277. package/docs/api/interfaces/RpcMethodsClientFuncParams.md +25 -0
  278. package/docs/api/interfaces/RpcMethodsServerFuncParams.md +61 -0
  279. package/docs/api/interfaces/SectionStringOptions.md +3 -3
  280. package/docs/api/interfaces/SemaphoreOptions.md +7 -7
  281. package/docs/api/interfaces/SemaphoreTaskItem.md +6 -6
  282. package/docs/api/interfaces/ServerFuncItem.md +22 -26
  283. package/docs/api/interfaces/ServerFuncParams.md +4 -3
  284. package/docs/api/interfaces/SplitSentenceOptions.md +5 -5
  285. package/docs/api/interfaces/StreamCallbacksAndOptions.md +11 -7
  286. package/docs/api/interfaces/TaskAbortControllers.md +1 -1
  287. package/docs/api/interfaces/TaskPromise.md +17 -9
  288. package/docs/api/interfaces/ToolFuncPackage.md +5 -5
  289. package/docs/api/type-aliases/AIChatContentPart.md +2 -2
  290. package/docs/api/type-aliases/AIChatMessageParam.md +2 -2
  291. package/docs/api/type-aliases/AIChatRole.md +2 -2
  292. package/docs/api/type-aliases/AIChatToolChoiceParam.md +2 -2
  293. package/docs/api/type-aliases/AIMessageType.md +2 -2
  294. package/docs/api/type-aliases/AIModelNameRule.md +2 -2
  295. package/docs/api/type-aliases/AIModelNameRuleFn.md +2 -2
  296. package/docs/api/type-aliases/AIModelNameRules.md +2 -2
  297. package/docs/api/type-aliases/AITextGenerationFinishReason.md +2 -2
  298. package/docs/api/type-aliases/ActionName.md +2 -2
  299. package/docs/api/type-aliases/ArrayMergeWay.md +2 -2
  300. package/docs/api/type-aliases/AsyncTaskId.md +2 -2
  301. package/docs/api/type-aliases/BeforeShutdownListener.md +2 -2
  302. package/docs/api/type-aliases/EventErrorListenerFn.md +2 -2
  303. package/docs/api/type-aliases/EventListenerFn.md +2 -2
  304. package/docs/api/type-aliases/FuncParamType.md +2 -2
  305. package/docs/api/type-aliases/PromptExamples.md +5 -3
  306. package/docs/api/type-aliases/PubSubClientId.md +2 -2
  307. package/docs/api/type-aliases/PubSubCtx.md +24 -4
  308. package/docs/api/type-aliases/RpcMethodHandler.md +2 -2
  309. package/docs/api/type-aliases/SSEClient.md +53 -0
  310. package/docs/api/type-aliases/SemaphoreIsReadyFuncType.md +2 -2
  311. package/docs/api/type-aliases/TFunc.md +2 -2
  312. package/docs/api/type-aliases/UUIDVersions.md +11 -0
  313. package/docs/api/variables/AIChatRoles.md +1 -1
  314. package/docs/api/variables/AIMessageTypes.md +1 -1
  315. package/docs/api/variables/AITextGenerationFinishReasons.md +1 -1
  316. package/docs/api/variables/ActionNames.md +1 -1
  317. package/docs/api/variables/ArrayMergeWay.md +2 -2
  318. package/docs/api/variables/ArrayMergeWaySymbol.md +2 -2
  319. package/docs/api/variables/ClientEventPrefix.md +11 -0
  320. package/docs/api/variables/ClientToolFuncSchema.md +4 -2
  321. package/docs/api/variables/DEFAULT_CONFIG_NAME.md +1 -1
  322. package/docs/api/variables/DefaultAsyncSemaphoreCapacity.md +1 -1
  323. package/docs/api/variables/EventBusName.md +1 -1
  324. package/docs/api/variables/EventName.md +1 -1
  325. package/docs/api/variables/FuncMetaSymbol.md +2 -2
  326. package/docs/api/variables/LLM_TOKENIZER_NAMES.md +4 -4
  327. package/docs/api/variables/LLM_TOKENIZER_NAMES_MAP.md +1 -1
  328. package/docs/api/variables/PASSING_SCORE.md +1 -1
  329. package/docs/api/variables/RStreamErrCode.md +1 -1
  330. package/docs/api/variables/RemoteToolFuncSchema.md +4 -2
  331. package/docs/api/variables/ResponseRStreamErrCode.md +1 -1
  332. package/docs/api/variables/RpcMethodsClientToolSchema.md +51 -0
  333. package/docs/api/variables/RpcMethodsServerToolSchema.md +21 -0
  334. package/docs/api/variables/SHUTDOWN_SIGNALS.md +1 -1
  335. package/docs/api/variables/SSEChannelAlreadyClosedErrCode.md +1 -1
  336. package/docs/api/variables/SecondaryCache.md +1 -1
  337. package/docs/api/variables/ServerToolFuncSchema.md +4 -2
  338. package/docs/api/variables/StrangeHumanName.md +1 -1
  339. package/docs/api/variables/ToolAsyncCancelableBit.md +1 -1
  340. package/docs/api/variables/ToolAsyncMultiTaskBit.md +1 -1
  341. package/docs/api/variables/ToolAsyncPriorityBit.md +1 -1
  342. package/docs/api/variables/ToolFuncSchema.md +4 -2
  343. package/docs/api/variables/backendEventable.md +11 -0
  344. package/docs/api/variables/base32768.md +1 -1
  345. package/docs/api/variables/event.md +1 -1
  346. package/docs/api/variables/eventClient.md +1 -1
  347. package/docs/api/variables/eventServer.md +1 -1
  348. package/docs/api/variables/lrucache.md +1 -1
  349. package/docs/api/variables/makeToolFuncCancelable.md +11 -0
  350. package/docs/api/{functions → variables}/wait.md +16 -14
  351. package/docs/pubsub.md +427 -105
  352. package/docs/server_client_tools.md +5 -3
  353. package/docs/toolFunc.md +3 -1
  354. package/package.json +10 -9
  355. package/dist/chunk-LNTIQQNN.mjs +0 -1
  356. package/docs/api/functions/backendEventable.md +0 -29
  357. package/docs/api/functions/makeToolFuncCancelable.md +0 -29
  358. package/docs/api/interfaces/PubSubClient.md +0 -27
  359. package/docs/api/namespaces/uuidv5/README.md +0 -12
@@ -1,20 +1,116 @@
1
1
  # Developer's Guide: Real-time Events with EventServer & EventClient
2
2
 
3
- This guide provides a comprehensive overview of the `EventServer` and `EventClient` tools, a powerful system for real-time, bidirectional communication. It is built on a **pluggable PubSub transport layer**, making it independent of the underlying communication protocol. You can use Server-Sent Events (SSE), WebSockets, IPC, or any other protocol by providing a corresponding transport implementation.
3
+ This guide provides a comprehensive overview of the `EventServer` and `EventClient` system, a powerful solution for building real-time, bidirectional communication channels. Its core architecture is built on a **pluggable PubSub transport layer**, making it completely independent of any specific communication protocol. You can seamlessly use Server-Sent Events (SSE), WebSockets, IPC, or any other protocol by simply providing a compatible transport implementation.
4
4
 
5
- **Prerequisite:** This document assumes you understand the base transport layer. If not, please review the [`transport_readme.md`](./transport_readme.md) first.
5
+ **Prerequisite:** This document assumes you understand the base transport layer. If not, please review the [`transport.md`](./transport.md) first.
6
6
 
7
7
  ## Core Concept: The Unified Event Bus
8
8
 
9
- The primary goal of this system is to create a seamless event bus that spans both the server and the client. It uses an abstract, pluggable PubSub transport for server-to-client messages and standard RPC calls for client-to-server messages.
9
+ The primary goal of this system is to create a seamless, bidirectional event bus that spans server and client enabling decoupled communication across your application.
10
+
11
+ It separates **control** and **data** planes:
12
+
13
+ * 🛠️ **Control Plane (RPC)**: Client-to-server event forwarding is **opt-in per event**. Call `eventClient.forwardEvent('event.name')` to enable it. Afterwards, `.emit('event.name', data)` automatically triggers an RPC call (via primary transport), sending the **original event name** (e.g., `'ui.click'`). The server **automatically prefixes it with `client:`** (e.g., `'client:ui.click'`) when processing, to avoid naming conflicts and enforce namespace isolation.
14
+ * 📡 **Data Plane (PubSub)**: Event payloads — whether originating from the server or resulting from client events processed by the server — are delivered asynchronously to clients via a dedicated, abstract, pluggable PubSub transport.
15
+
16
+ The key feature is **configurable event forwarding**:
17
+
18
+ * 🔁 The server can be configured to listen to its internal global `eventBus` and automatically relay selected events to subscribed clients via PubSub.
19
+ * 🔁 **Client → Server event forwarding requires two explicit, independent opt-ins:**
20
+ 1. **Client-side**: Call `eventClient.forwardEvent('event.name')` to enable RPC publishing for that specific event.
21
+ 2. **Server-side**: Set `EventServer.forwardClientPublishes = true` to allow received events (after being prefixed with `client:`) to be emitted on the server’s internal event bus.
22
+
23
+ ```ts
24
+ // Step 1: Client enables forwarding for a specific event
25
+ eventClient.forwardEvent('ui.click');
26
+
27
+ // Step 2: Server enables processing of client-originated events
28
+ EventServer.forwardClientPublishes = true;
29
+ ```
30
+
31
+ ⚠️ **Important**: The event handling methods (`.on()`, `.off()`, `.emit()` etc) are **not native** to `EventClient` and `EventServer`. Their event capabilities must be **injected via the `backendEventable(...)` function**. Attempting to call these methods before injection will result in a `TypeError`.
32
+
33
+ This design creates a powerful, loosely-coupled architecture where components communicate through events without direct dependencies, location transparency, or transport concerns. The use of AOP (backendEventable) for capability injection ensures maximum flexibility, testability, and explicit opt-in behavior.
34
+
35
+ ```md
36
+ ┌──────────────────────────────────────────────────────────────────────────────┐
37
+ │ │
38
+ │ ┌────────────────┐ uses ┌─────────────────────┐ │
39
+ │ │ EventClient │ ──────────────▶ │ ClientTransport │ │
40
+ │ │ - InjectEmitter│ (RPC Call) │ (HTTP/WebSocket RPC)│ │
41
+ │ │ - forwardEvent │ ◀─────────────▶ │ │ │
42
+ │ └────────────────┘ └────────┬────────────┘ │
43
+ │ │ RPC: publish('my.event') │
44
+ │ ▼ │
45
+ │ ┌─────────────────────┐ │
46
+ │ │ ServerTransport │ │
47
+ │ │ (HTTP/WebSocket RPC)│ │
48
+ │ └──────────┬──────────┘ │
49
+ │ │ │
50
+ │ ▼ │
51
+ │ ┌─────────────────────────────┐ │
52
+ │ │ EventServer │ │
53
+ │ │ - Inject Emitter │ │
54
+ │ │ - forwardClientPublishes │ │
55
+ │ │ emit('client:ui.click') │ │
56
+ │ └──────────┬──────────────────┘ │
57
+ │ │ Broadcast │
58
+ │ ▼ │
59
+ │ ┌─────────────────────┐ │
60
+ │ │PubSubServerTransport│ │
61
+ │ │ (WebSocket/MQTT) │ │
62
+ │ └──────────┬──────────┘ │
63
+ │ │ PubSub Message │
64
+ │ ▼ │
65
+ │ ┌─────────────────────┐ │
66
+ │ │PubSubClientTransport│ │
67
+ │ │ (WebSocket/MQTT) │ │
68
+ │ └──────────┬──────────┘ │
69
+ │ │ Deliver Message │
70
+ │ ▼ │
71
+ │ ┌───────────────────────┐ │
72
+ │ │ EventClient │ │
73
+ │ │ → Receive and trigger │ │
74
+ │ │ local events │ │
75
+ │ └───────────────────────┘ │
76
+ │ │
77
+ └──────────────────────────────────────────────────────────────────────────────┘
78
+ ```
10
79
 
11
- The key feature is the ability to **"forward"** events. You can configure the server to automatically listen for events on its internal, global `eventBus` and relay them to clients. Likewise, you can configure the client to forward its local events to the server. This creates a powerful, decoupled architecture where different parts of your application can communicate without direct dependencies.
80
+ ```mermaid
81
+ graph TD
82
+ %% ========== Client Side ==========
83
+ EC[EventClient<br><i>需 backendEventable 注入 .on/.off/.emit</i>]
84
+ CT[ClientTransport<br><i>RPC: 发起 publish/subscribe</i>]
85
+ PCT[PubSubClientTransport<br><i>接收服务端广播事件</i>]
86
+
87
+ %% ========== Server Side ==========
88
+ ES[EventServer<br><i>需 backendEventable 注入 .on/.off/.emit</i>]
89
+ ST[ServerTransport<br><i>RPC: 接收 publish/subscribe</i>]
90
+ PST[PubSubServerTransport<br><i>向客户端广播事件</i>]
91
+
92
+ %% ========== Connections ==========
93
+ EC -- "RPC: publish('client:xxx', data)(需 forwardEvent)" --> CT
94
+ CT -- "→ RPC 请求" --> ST
95
+ ST -- "→ 交由 EventServer 处理" --> ES
96
+
97
+ ES -- "PubSub: 广播事件" --> PST
98
+ PST -- "→ PubSub 消息" --> PCT
99
+ PCT -- "→ 交由 EventClient 分发" --> EC
100
+
101
+ class EC client
102
+ class ES server
103
+ class CT,ST rpc
104
+ class PCT,PST pubsub
105
+ ```
12
106
 
13
107
  ### Aspect-Oriented Programming (AoP) and Event Emitters
14
108
 
15
109
  A crucial concept is that `EventClient` (and `ClientTools` in general) can be enhanced with event emitter capabilities. By using a library like `events-ex`, you can give your client-side tool instances standard `on`, `off`, and `emit` methods. This allows `EventClient` to act as a local event bus that is transparently synchronized with the server.
16
110
 
17
- ## Example 1: HTTP and Server-Sent Events (SSE)
111
+ > 💡 Event listening and emitting capabilities are injected into `EventClient` via the AOP-style `backendEventable(EventClient)` function, keeping the core class transport-agnostic and easily testable.
112
+
113
+ ## Example: HTTP and Server-Sent Events (SSE)
18
114
 
19
115
  ### Architecture (SSE)
20
116
 
@@ -35,9 +131,9 @@ graph TD
35
131
  end
36
132
 
37
133
  subgraph Server-Side
38
- S_Transport[FastifyServerToolTransport] -- "receives RPC" --> ES[EventServer]
39
- ES -- "uses" --> S_PubSub[SseServerPubSubTransport]
40
- S_PubSub -- "handles SSE connections" --> ES
134
+ S_Transport[HttpServerToolTransport] -- "receives RPC" --> ES[EventServer]
135
+ ES -- "delegates to" --> S_PubSub[SseServerPubSubTransport]
136
+ S_PubSub -- "handles SSE connection" --> ES
41
137
  ES -- "interacts with" --> S_EventBus[Global Server EventBus]
42
138
  OtherServices[Other Server Logic] -- "emit/on" --> S_EventBus
43
139
  end
@@ -49,13 +145,13 @@ graph TD
49
145
 
50
146
  ### Server-Side Setup (SSE)
51
147
 
52
- In your server setup, you must first tell `EventServer` which transport to use, then register the `eventServer` instance.
148
+ On the server, you must set the desired PubSub transport on the `EventServer` class. When a client makes a request to the `eventServer`'s `list` endpoint, the `EventServer` delegates the connection handling to the transport.
53
149
 
54
150
  ```typescript
55
151
  // In your server entry file (e.g., server.ts)
56
152
  import {
57
153
  eventServer,
58
- FastifyServerToolTransport,
154
+ HttpServerToolTransport, // Using a generic HTTP transport
59
155
  ResServerTools,
60
156
  EventServer, // Import EventServer class
61
157
  SseServerPubSubTransport // Import the SSE transport
@@ -68,7 +164,7 @@ async function main() {
68
164
  // Register the eventServer tool instance
69
165
  eventServer.register();
70
166
 
71
- const serverTransport = new FastifyServerToolTransport();
167
+ const serverTransport = new HttpServerToolTransport();
72
168
  // Mount the base class; the transport finds all registered tools
73
169
  serverTransport.mount(ResServerTools, '/api');
74
170
 
@@ -79,7 +175,7 @@ async function main() {
79
175
 
80
176
  ### Client-Side Setup (SSE)
81
177
 
82
- On the client, you must set the appropriate PubSub transport (matching the server's), enhance the `EventClient` with `EventEmitter` capabilities, and register the instance.
178
+ On the client, the setup is designed to be simple and robust. You set up your main RPC transport first, and then you set the PubSub transport. The `EventClient` is smart enough to automatically configure the PubSub transport with the `apiRoot` from the main transport.
83
179
 
84
180
  ```typescript
85
181
  // In your client-side code
@@ -93,101 +189,221 @@ import {
93
189
  } from '@isdk/ai-tool';
94
190
 
95
191
  async function main() {
96
- const apiRoot = 'http://localhost:3003/api';
97
- const clientTransport = new HttpClientToolTransport(apiRoot);
98
- await clientTransport.mount(ResClientTools);
192
+ const apiRoot = 'http://localhost:3000/api';
193
+ const clientTransport = new HttpClientToolTransport();
194
+ // Mount the main transport, which configures the static ClientTools.apiRoot
195
+ await clientTransport.mount(ResClientTools, apiRoot);
99
196
 
100
197
  // **Crucial Step 1: Set the PubSub transport for the client**
198
+ // It is **critical** that `setPubSubTransport` is called *after* the main
199
+ // transport has been mounted, as this is what makes the `apiRoot` available
200
+ // for automatic configuration.
101
201
  EventClient.setPubSubTransport(new SseClientPubSubTransport());
102
202
 
103
203
  // **Crucial Step 2: Make the client eventable**
104
204
  backendEventable(EventClient);
105
205
  eventClient.register();
106
206
 
107
- // Now you can use eventClient.on, .off, .emit
207
+ // Now you can use eventClient.on, .off, .emit to interact with the server
108
208
  }
109
209
  ```
110
210
 
111
- ---
211
+ ## Example: Electron IPC for Real-time Desktop Apps
212
+
213
+ For desktop applications built with Electron, the event system can operate over the built-in Inter-Process Communication (IPC) channels. This provides a highly efficient, real-time backend within your application shell without needing an HTTP server.
112
214
 
113
- ## Example 2: Electron IPC Transport
215
+ We will cover two scenarios: using IPC for Pub/Sub only, and a fully integrated approach where both RPC and Pub/Sub use IPC.
114
216
 
115
- This transport uses Electron's Inter-Process Communication (IPC) to create an event bus between the main process (server) and renderer processes (clients).
217
+ ### Scenario 1: Standalone Pub/Sub over IPC
116
218
 
117
- ### Server-Side Setup (Electron Main Process)
219
+ This approach is ideal if you only need a real-time eventing layer or if your main RPC communication uses a different transport (e.g., HTTP).
118
220
 
119
- In your Electron main process, you instantiate an `ElectronServerPubSubTransport` with a unique namespace. This namespace acts like an `apiRoot` and ensures that different event buses don't conflict.
221
+ #### Main Process Setup (`main.ts`)
222
+
223
+ You only need to set up the `ElectronServerPubSubTransport` and tell it to start listening.
120
224
 
121
225
  ```typescript
122
- // In your Electron main process (e.g., main.ts)
123
- import {
124
- EventServer,
125
- eventServer,
126
- ElectronServerPubSubTransport,
127
- } from '@isdk/ai-tool';
226
+ // In your main Electron process (e.g., main.ts)
227
+ import { EventServer, ElectronServerPubSubTransport } from '@isdk/ai-tool';
128
228
 
129
- // 1. Define a unique namespace for this event bus
130
- const electronApiRoot = '/electron/events';
229
+ // 1. Define a unique namespace for your pub/sub channels.
230
+ const pubSubNamespace = 'my-app-events';
131
231
 
132
- // 2. Create a transport instance for this specific namespace
133
- const electronTransport = new ElectronServerPubSubTransport(electronApiRoot);
232
+ // 2. Create an instance of the server transport.
233
+ const serverTransport = new ElectronServerPubSubTransport(pubSubNamespace);
134
234
 
135
- // 3. Set the transport on the EventServer
136
- // Note: This is a static property. For multiple, different event servers
137
- // (e.g., one for SSE, one for Electron), you would create subclasses of EventServer
138
- // to hold each static transport instance separately.
139
- EventServer.setPubSubTransport(electronTransport);
235
+ // 3. Set the transport for the global EventServer.
236
+ EventServer.setPubSubTransport(serverTransport);
140
237
 
141
- // 4. Register the eventServer tool instance. It will now use the Electron transport.
142
- eventServer.register();
238
+ // 4. **Crucial Step: Activate the transport's IPC listeners.**
239
+ serverTransport.listen();
143
240
 
144
- // Now you can use the global eventBus to emit events, and the EventServer
145
- // will forward them to any connected renderer process.
241
+ // Now the EventServer is ready. You can publish events from anywhere
242
+ // in the main process, and they will be sent to subscribed renderers.
243
+ console.log('[Main] Pub/Sub transport listening...');
244
+ setInterval(() => {
245
+ EventServer.publish('server-tick', { timestamp: Date.now() });
246
+ }, 5000);
146
247
  ```
147
248
 
148
- ### Client-Side Setup (Electron Renderer Process)
149
-
150
- In the renderer process, you must use the same namespace (`apiRoot`) to connect to the correct event bus in the main process.
249
+ #### Renderer Process Setup (`renderer.ts`)
151
250
 
152
- **Important:** The `EventClient` still relies on an RPC mechanism for actions like `subscribe` and `unsubscribe`. You must have a corresponding RPC transport set up between the renderer and main process for the full functionality to work. The example below focuses only on setting up the PubSub portion.
251
+ The client setup is also straightforward. You must configure the `EventClient` with the same namespace.
153
252
 
154
253
  ```typescript
155
- // In your Electron renderer process (e.g., preload.ts or renderer.ts)
156
- import {
157
- EventClient,
158
- eventClient,
159
- ElectronClientPubSubTransport,
160
- backendEventable,
161
- } from '@isdk/ai-tool';
254
+ // In your client-side code (e.g., renderer.ts)
255
+ import { EventClient, eventClient, ElectronClientPubSubTransport, backendEventable } from '@isdk/ai-tool';
162
256
 
163
- // 1. The apiRoot MUST match the namespace used in the main process
164
- const electronApiRoot = '/electron/events';
257
+ // 1. Use the same namespace as the server.
258
+ const pubSubNamespace = 'my-app-events';
165
259
 
166
- // 2. Set the PubSub transport on the EventClient class
260
+ // 2. Set the PubSub transport for the client.
167
261
  EventClient.setPubSubTransport(new ElectronClientPubSubTransport());
168
262
 
169
- // 3. Make the EventClient class event-aware
170
- backendEventable(EventClient);
263
+ // 3. **Crucial Step: Configure the EventClient with the namespace.**
264
+ // This is used as the 'apiRoot' to determine which IPC channels to use.
265
+ EventClient.apiRoot = pubSubNamespace;
171
266
 
172
- // 4. Configure the eventClient INSTANCE
173
- // This tells the client which event bus to connect to.
174
- eventClient.setApiRoot(electronApiRoot);
267
+ // 4. Make the client eventable and register it.
268
+ backendEventable(EventClient);
175
269
  eventClient.register();
176
270
 
177
- // 5. Now you can use the event client
178
- async function setupEvents() {
179
- await eventClient.subscribe('some-event-from-main');
271
+ // 5. Subscribe to events. This automatically triggers the connection to the main process.
272
+ await eventClient.subscribe('server-tick');
180
273
 
181
- eventClient.on('some-event-from-main', (data) => {
182
- console.log('Received event from main process:', data);
183
- });
274
+ eventClient.on('server-tick', (data) => {
275
+ console.log('Received tick from main process:', data);
276
+ document.body.innerHTML = `Tick received at: ${data.timestamp}`;
277
+ });
278
+ ```
279
+
280
+ > **Note on Security**: This simple example assumes `contextIsolation` is disabled. For modern, secure Electron apps, please see the integrated example below which includes a `preload.js` script.
281
+
282
+ ### Scenario 2: Integrated RPC and Pub/Sub over IPC
283
+
284
+ This is the recommended, fully-native approach for Electron apps. It provides both request-response (RPC) and real-time events over the same efficient IPC foundation. This requires a `preload.js` script to securely bridge the main and renderer processes.
184
285
 
185
- // Forward a local event to the main process
186
- eventClient.forwardEvent('event-from-renderer');
187
- eventClient.emit('event-from-renderer', { my: 'data' });
286
+ #### Part 1: Preload Script (`preload.ts`)
287
+
288
+ This script acts as a secure bridge, exposing only the necessary IPC functions to the renderer process. Your `BrowserWindow` webPreferences should point to this file.
289
+
290
+ ```typescript
291
+ // preload.ts
292
+ import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
293
+
294
+ // Define the API that will be exposed to the renderer process via `window.electronApi`
295
+ const electronApi = {
296
+ // For RPC (invoke/handle)
297
+ invoke: (channel: string, ...args: any[]) => ipcRenderer.invoke(channel, ...args),
298
+
299
+ // For Pub/Sub (send/on)
300
+ send: (channel: string, ...args: any[]) => ipcRenderer.send(channel, ...args),
301
+ on: (channel: string, listener: (event: IpcRendererEvent, ...args: any[]) => void) => {
302
+ ipcRenderer.on(channel, listener);
303
+ },
304
+ off: (channel: string, listener: (...args: any[]) => void) => {
305
+ ipcRenderer.removeListener(channel, listener);
306
+ },
307
+ };
308
+
309
+ // Securely expose the API to the renderer's window object
310
+ contextBridge.exposeInMainWorld('electronApi', electronApi);
311
+
312
+ // Optional: Define a type for your exposed API for better TypeScript support
313
+ export type ElectronApi = typeof electronApi;
314
+ ```
315
+
316
+ #### Part 2: Main Process Setup (`main.ts`)
317
+
318
+ Here, we set up both the `IpcServerToolTransport` for RPC and the `ElectronServerPubSubTransport` for Pub/Sub.
319
+
320
+ ```typescript
321
+ // main.ts
322
+ import { IpcServerToolTransport } from '@isdk/ai-tool';
323
+ import { ElectronServerPubSubTransport } from '@isdk/ai-tool';
324
+ import { EventServer, ResServerTools, eventServer } from '@isdk/ai-tool';
325
+
326
+ // Use a single, consistent namespace for all IPC channels
327
+ const channelNamespace = 'my-app';
328
+
329
+ // --- 1. Setup IPC for standard RPC ---
330
+ const rpcTransport = new IpcServerToolTransport();
331
+ // This sets up handlers for 'my-app:discover' and 'my-app:rpc'.
332
+ rpcTransport.mount(ResServerTools, channelNamespace);
333
+ rpcTransport.start();
334
+ console.log(`[Main] RPC transport started on namespace: ${channelNamespace}`);
335
+
336
+ // --- 2. Setup IPC for Pub/Sub ---
337
+ const pubsubTransport = new ElectronServerPubSubTransport(channelNamespace);
338
+ EventServer.setPubSubTransport(pubsubTransport);
339
+ pubsubTransport.listen(); // Activate the pub/sub listeners
340
+ console.log(`[Main] Pub/Sub transport listening on namespace: ${channelNamespace}`);
341
+
342
+ // --- 3. Register Tools ---
343
+ // Register the eventServer so its methods (sub, unsub) can be called via RPC
344
+ eventServer.register();
345
+ ```
346
+
347
+ #### Part 3: Renderer Process Setup (`renderer.ts`)
348
+
349
+ The renderer will use the `electronApi` exposed by the preload script. To make this work seamlessly, you can create simple wrapper classes for your transports that use the bridged API instead of the raw `ipcRenderer`.
350
+
351
+ ```typescript
352
+ // renderer.ts
353
+ import { IpcClientToolTransport, ElectronClientPubSubTransport, EventClient, ResClientTools, eventClient, backendEventable } from '@isdk/ai-tool';
354
+ import type { ElectronApi } from './preload';
355
+
356
+ // Make the bridged API available on the window object for TypeScript
357
+ declare global {
358
+ interface Window { electronApi: ElectronApi; }
359
+ }
360
+
361
+ // --- Custom Transports Using the Secure Bridge ---
362
+
363
+ // 1. Create a custom RPC transport that uses the bridged `invoke` method.
364
+ class SecureIpcRpcTransport extends IpcClientToolTransport {
365
+ async _fetch(name: string, args?: any, act?: any, subName?: any) {
366
+ const payload = { toolId: name, params: args || {}, act, id: subName };
367
+ return window.electronApi.invoke(this.channels.rpc, payload);
368
+ }
369
+ async loadApis() {
370
+ return window.electronApi.invoke(this.channels.discover);
371
+ }
372
+ }
373
+
374
+ // 2. Create a custom Pub/Sub transport that uses the bridged API.
375
+ // This pattern requires that the base transport class allows for dependency injection.
376
+ class SecureIpcPubSubTransport extends ElectronClientPubSubTransport {
377
+ constructor() {
378
+ // Pass the bridged API to the constructor instead of letting it use the global ipcRenderer
379
+ super(window.electronApi as any);
380
+ }
188
381
  }
189
382
 
190
- setupEvents();
383
+ // --- Application Setup ---
384
+ async function main() {
385
+ const channelNamespace = 'my-app';
386
+
387
+ // Use the secure RPC transport
388
+ const rpcTransport = new SecureIpcRpcTransport();
389
+ await rpcTransport.mount(ResClientTools, channelNamespace);
390
+
391
+ // Use the secure Pub/Sub transport
392
+ const pubsubTransport = new SecureIpcPubSubTransport();
393
+ EventClient.setPubSubTransport(pubsubTransport);
394
+ EventClient.apiRoot = channelNamespace;
395
+
396
+ backendEventable(EventClient);
397
+ eventClient.register();
398
+
399
+ // Now you can use RPC and Pub/Sub together seamlessly and securely!
400
+ await eventClient.subscribe('server-time');
401
+ eventClient.on('server-time', (data) => {
402
+ console.log('Received time from main:', data);
403
+ });
404
+ }
405
+
406
+ main();
191
407
  ```
192
408
 
193
409
  ---
@@ -198,52 +414,105 @@ Once the setup is complete, the API for using the event bus is the same regardle
198
414
 
199
415
  ### Forwarding and Publishing Events (Server-Side)
200
416
 
201
- The server can push events to clients either by forwarding them from a central event bus or by publishing them directly. With the latest updates, the `publish` method now supports targeted delivery to specific clients, in addition to broadcasting.
417
+ There are two ways to send events from the server to clients: through the global `eventBus` (standard approach) or by publishing directly to the transport (advanced approach).
202
418
 
203
- **Note:** The availability of targeted publishing depends on the underlying transport implementation. While the `EventServer` API supports it, some transports (like the current SSE transport) may only be capable of broadcasting.
419
+ #### Standard Approach: Forwarding from the Event Bus
420
+
421
+ The recommended and most common way to send events is to emit them on the global `eventBus`. You can configure the `eventServer` to automatically listen for specific events on this bus and forward them to subscribed clients. This creates a clean, decoupled architecture.
204
422
 
205
423
  ```typescript
206
- import { eventServer, EventServer } from '@isdk/ai-tool';
424
+ import { eventServer } from '@isdk/ai-tool';
207
425
  import { event } from '@isdk/ai-tool/funcs/event'; // The global eventBus
208
426
 
209
427
  const eventBus = event.runSync();
210
428
 
211
- // **Forwarding (Recommended)**
212
- // Automatically relay events from the global eventBus to subscribed clients.
429
+ // 1. Configure the server to forward events.
213
430
  eventServer.forward(['user-updated', 'item-added']);
214
431
 
215
- // Now, any other part of your server can simply emit events on the bus:
432
+ // 2. Now, any other part of your server can simply emit events on the bus.
216
433
  function updateUser(user: any) {
217
434
  eventBus.emit('user-updated', { userId: user.id, status: 'active' });
218
435
  }
436
+ ```
437
+
438
+ #### Advanced Approach: Direct Publishing to the Transport
219
439
 
220
- // **Direct Publishing**
221
- // The `EventServer.publish` method allows sending an event directly to clients.
222
- // Its signature is: `publish(event: string, data: any, target?: { clientId: string | string[] })`.
440
+ For special cases where you need to bypass the global `eventBus` and send an event directly to the transport layer, you can use the static `EventServer.publish()` method.
223
441
 
224
- // 1. Broadcast to all clients subscribed to 'broadcast-message'.
225
- // This is the default behavior when `target` is omitted.
442
+ This is an advanced feature. For it to work correctly, the client must have explicitly registered its interest in the event at the transport level, typically by using `eventClient.init(['event-name'])`.
443
+
444
+ ```typescript
445
+ import { EventServer } from '@isdk/ai-tool';
446
+
447
+ // The signature is: `publish(event: string, data: any, target?: { clientId: string | string[] })`.
448
+
449
+ // 1. Broadcast to all clients that used init() to subscribe to 'broadcast-message'.
226
450
  function sendBroadcast() {
227
451
  EventServer.publish('broadcast-message', { message: 'Server is restarting soon!' });
228
452
  }
229
453
 
230
454
  // 2. Send a targeted event to a specific client.
231
- // This requires knowing the `clientId` of the recipient.
232
455
  function sendDirectMessage(clientId: string, message: string) {
233
456
  const target = { clientId };
234
457
  EventServer.publish('private-message', { text: message }, target);
235
458
  }
459
+ ```
236
460
 
237
- // 3. Send an event to a group of specific clients.
238
- function sendToGroup(clientIds: string[], message: string) {
239
- const target = { clientId: clientIds };
240
- EventServer.publish('group-message', { text: message }, target);
241
- }
461
+ ### Receiving and Distinguishing Events on the Server
462
+
463
+ A key design feature of the event system is the clear, safe separation between events originating from the server's internal logic and events published by clients. This is achieved by automatically prefixing all client-originated events with `client:`.
464
+
465
+ This mechanism prevents clients from accidentally or maliciously triggering sensitive internal events, and allows server-side plugins to focus on business logic without needing to manually check the origin of every event.
466
+
467
+ #### Enabling/Disabling Client Event Forwarding
468
+
469
+ By default, events published by clients are **not** forwarded to the server's internal event bus. This is a security-first approach that prevents unwanted side effects.
470
+
471
+ To enable this feature, you must set the static `forwardClientPublishes` property to `true` during your server setup.
472
+
473
+ ```typescript
474
+ // In your server entry file
475
+ import { EventServer } from '@isdk/ai-tool';
476
+
477
+ // Set to true to allow client events to be emitted on the server bus.
478
+ EventServer.forwardClientPublishes = true;
479
+ ```
480
+
481
+ Only when this is set to `true` will the server emit `client:` prefixed events on its internal bus.
482
+
483
+ #### Example 1: Listening for an Internal Server Event
484
+
485
+ This is the standard way to listen for events that are part of the server's own workflow. This listener will **never** be triggered by a client publishing an event with the same name.
242
486
 
243
- // **Receiving Client Events**
244
- // Listen for events that were published or forwarded from a client.
245
- eventBus.on('client-action', (data: any, event: any) => {
246
- console.log(`Received event "$\{event.type\}" from a client:`, data);
487
+ ```typescript
488
+ import { event } from '@isdk/ai-tool/funcs/event';
489
+ const eventBus = event.runSync();
490
+
491
+ // Listens for an event triggered only by server-side logic.
492
+ // e.g., eventBus.emit('data-updated', { id: 123 });
493
+ eventBus.on('data-updated', (data) => {
494
+ console.log('Internal data has been updated. Refreshing cache...');
495
+ // ...purely internal business logic
496
+ });
497
+ ```
498
+
499
+ #### Example 2: Listening for a Client-Originated Event
500
+
501
+ To react to an event published by a client, you must explicitly listen for the event name with the `client:` prefix. The listener will also receive a metadata object containing the trusted, server-verified `clientId`.
502
+
503
+ ```typescript
504
+ import { event } from '@isdk/ai-tool/funcs/event';
505
+ const eventBus = event.runSync();
506
+
507
+ // A client publishes an event like:
508
+ // eventClient.publish({ event: 'user-action', data: { ... } });
509
+
510
+ // The server-side listener must use the 'client:' prefix.
511
+ eventBus.on('client:user-action', (data, meta) => {
512
+ // The 'meta' object contains the trusted clientId from the transport layer.
513
+ const { clientId } = meta;
514
+ console.log(`User ${clientId} performed an action with data:`, data);
515
+ // ...logic to handle the client interaction
247
516
  });
248
517
  ```
249
518
 
@@ -258,6 +527,9 @@ eventClient.on('user-updated', (data: any) => {
258
527
  });
259
528
 
260
529
  // **Publish an Event to the Server**
530
+ // This sends the event to the server. On the server's internal event bus,
531
+ // it will be prefixed and emitted as 'client:client-action'.
532
+ // Other clients will receive it as the original 'client-action'.
261
533
  eventClient.publish({
262
534
  event: 'client-action',
263
535
  data: { action: 'button-click', value: 123 }
@@ -267,6 +539,8 @@ eventClient.publish({
267
539
  eventClient.forwardEvent(['user-settings-changed']);
268
540
 
269
541
  function onSettingsSave(newSettings: any) {
542
+ // This emits the event on the local event bus. Because it was forwarded,
543
+ // it will also be published to the server.
270
544
  eventClient.emit('user-settings-changed', newSettings);
271
545
  }
272
546
  ```
@@ -277,7 +551,11 @@ This transport-agnostic architecture provides a clean, powerful, and decoupled w
277
551
 
278
552
  ## Implementing a Custom PubSub Transport
279
553
 
280
- For developers who need to integrate a different messaging protocol (e.g., WebSockets, MQTT), you can create your own transport by implementing the `IPubSubServerTransport` interface from `@isdk/ai-tool/transports/pubsub/server`.
554
+ For developers who need to integrate a different messaging protocol (e.g., WebSockets, MQTT), you can create your own transport by implementing the server-side and client-side PubSub interfaces.
555
+
556
+ ### Server-Side: `IPubSubServerTransport`
557
+
558
+ The server-side implementation is responsible for managing client connections and broadcasting events. You implement the `IPubSubServerTransport` interface from `@isdk/ai-tool/transports/pubsub/server`.
281
559
 
282
560
  The core interface is defined as follows:
283
561
 
@@ -286,25 +564,32 @@ export interface IPubSubServerTransport {
286
564
  readonly name: string;
287
565
  readonly protocol: string;
288
566
 
289
- // Optional: For transports that need to hook into an HTTP server
290
- mount?: (path: string, options?: Record<string, any>) => void;
291
-
292
- // Establish a connection with a client and subscribe them to events.
293
- // The `options` object is a generic container for transport-specific
294
- // parameters, like HTTP request/response objects for SSE.
567
+ /**
568
+ * Subscribes a client to an event stream by taking over an incoming request.
569
+ *
570
+ * This method is designed to be generic. Transport-specific details, such as
571
+ * HTTP request/response objects, are passed inside the `options` parameter.
572
+ *
573
+ * @param events Optional array of event names to initially subscribe the client to.
574
+ * @param options A container for transport-specific parameters.
575
+ * @returns A `PubSubClient` object representing the newly connected client.
576
+ */
295
577
  subscribe: (
296
578
  events?: string[],
297
579
  options?: {
298
- req?: any;
299
- res?: any;
580
+ req: any; // e.g., http.IncomingMessage
581
+ res: any; // e.g., http.ServerResponse
300
582
  clientId?: string;
301
583
  [k: string]: any;
302
584
  }
303
585
  ) => PubSubClient; // Return a client object, minimally with a `clientId`.
304
586
 
305
- // Publish an event from the server to clients.
306
- // The `target` parameter allows for broadcasting (default) or
307
- // targeted delivery to specific client IDs.
587
+ /**
588
+ * Publishes an event from the server to clients.
589
+ *
590
+ * The `target` parameter allows for broadcasting (default) or
591
+ * targeted delivery to specific client IDs.
592
+ */
308
593
  publish: (
309
594
  event: string,
310
595
  data: any,
@@ -315,12 +600,49 @@ export interface IPubSubServerTransport {
315
600
  onConnection: (cb: (session: PubSubServerSession) => void) => void;
316
601
  onDisconnect: (cb: (session: PubSubServerSession) => void) => void;
317
602
 
318
- // Optional: For bidirectional transports (e.g., WebSockets)
319
- // to handle messages received from the client.
603
+ /**
604
+ * Optional: For bidirectional transports (e.g., WebSockets)
605
+ * to handle messages received from the client.
606
+ */
320
607
  onMessage?: (
321
608
  cb: (session: PubSubServerSession, event: string, data: any) => void
322
609
  ) => void;
323
610
  }
324
611
  ```
325
612
 
326
- By implementing this interface, your custom transport can be plugged directly into the `EventServer` using `EventServer.setPubSubTransport(new YourCustomTransport())`, enabling the entire real-time event system over your chosen protocol.
613
+ By implementing this interface, your custom transport can be plugged directly into the `EventServer` using `EventServer.setPubSubTransport(new YourCustomTransport())`.
614
+
615
+ ### Client-Side: `IPubSubClientTransport`
616
+
617
+ The client-side implementation is responsible for establishing a connection to the server and receiving events. This is defined by the `IPubSubClientTransport` interface from `@isdk/ai-tool/transports/pubsub/client`.
618
+
619
+ The core interface is defined as follows:
620
+
621
+ ```typescript
622
+ export interface IPubSubClientTransport {
623
+ /**
624
+ * Establishes a connection to a server endpoint.
625
+ * @param url The path of the endpoint, relative to the `apiRoot` configured on the transport. For advanced use or compatibility, this can also be a full, absolute URL.
626
+ * @param params Optional parameters for the connection, such as initial event subscriptions.
627
+ * @returns A `PubSubClientStream` instance representing the connection.
628
+ */
629
+ connect: (url: string, params?: Record<string, any>) => PubSubClientStream;
630
+
631
+ /**
632
+ * Optional. Disconnects a given stream.
633
+ */
634
+ disconnect?: (stream: PubSubClientStream) => void;
635
+
636
+ /**
637
+ * Optional. Configures the transport with a base URL.
638
+ * If implemented, this allows the transport to resolve relative paths
639
+ * passed to the `connect` method. This is called automatically by `EventClient.setPubSubTransport`.
640
+ * @param apiRoot The base URL for the API.
641
+ */
642
+ setApiRoot?: (apiRoot: string) => void;
643
+ }
644
+ ```
645
+
646
+ The `EventClient` automatically handles the `apiRoot` configuration, making the system easy to use. The `connect` method is the most critical part, as it decouples the `EventClient` from the specifics of how a connection is made.
647
+
648
+ By implementing both interfaces, you can enable the entire real-time event system over your chosen protocol.