@db3.ai/app 0.1.0-beta.1 → 0.1.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 (653) hide show
  1. package/README.md +75 -17
  2. package/agent-instructions.md +76 -0
  3. package/dist/ai/AIErrors.d.ts +7 -1
  4. package/dist/ai/AIErrors.js +8 -1
  5. package/dist/ai/AIFailover.d.ts +10 -0
  6. package/dist/ai/AIFailover.js +3 -2
  7. package/dist/ai/AIProviderAdmission.d.ts +101 -0
  8. package/dist/ai/AIProviderAdmission.js +336 -0
  9. package/dist/ai/AIRateLimiter.d.ts +11 -2
  10. package/dist/ai/AIRateLimiter.js +125 -10
  11. package/dist/ai/AIRequestTrackingError.d.ts +22 -0
  12. package/dist/ai/AIRequestTrackingError.js +33 -0
  13. package/dist/ai/Agent.d.ts +7 -7
  14. package/dist/ai/Agent.js +84 -56
  15. package/dist/ai/Ai.d.ts +11 -3
  16. package/dist/ai/Ai.js +94 -44
  17. package/dist/ai/OpenAIProviderError.js +1 -1
  18. package/dist/ai/ProviderSseObserver.d.ts +19 -0
  19. package/dist/ai/ProviderSseObserver.js +98 -0
  20. package/dist/ai/aiServiceTier.d.ts +5 -0
  21. package/dist/ai/aiServiceTier.js +14 -0
  22. package/dist/ai/chunkEmbeddingText.d.ts +14 -0
  23. package/dist/ai/chunkEmbeddingText.js +147 -0
  24. package/dist/ai/contracts/AI.d.ts +16 -0
  25. package/dist/ai/contracts/AIRequestErrorDiagnostics.d.ts +12 -0
  26. package/dist/ai/contracts/AIRequestErrorDiagnostics.js +1 -0
  27. package/dist/ai/contracts/AIServiceTier.d.ts +2 -0
  28. package/dist/ai/contracts/AIServiceTier.js +1 -0
  29. package/dist/ai/contracts/Agent.d.ts +3 -0
  30. package/dist/ai/contracts/EmbeddingTextChunk.d.ts +25 -0
  31. package/dist/ai/contracts/EmbeddingTextChunk.js +1 -0
  32. package/dist/ai/contracts/Pricing.d.ts +7 -1
  33. package/dist/ai/contracts/Providers.d.ts +2 -0
  34. package/dist/ai/contracts/index.d.ts +2 -0
  35. package/dist/ai/contracts/index.js +1 -0
  36. package/dist/ai/index.d.ts +8 -2
  37. package/dist/ai/index.js +5 -2
  38. package/dist/ai/{Models.d.ts → modelPricing.d.ts} +2 -2
  39. package/dist/ai/{Models.js → modelPricing.js} +38 -4
  40. package/dist/apps/AppInstallation.d.ts +21 -0
  41. package/dist/apps/AppInstallation.js +16 -0
  42. package/dist/apps/AppRouteError.d.ts +6 -0
  43. package/dist/apps/AppRouteError.js +10 -0
  44. package/dist/apps/AppService.d.ts +24 -0
  45. package/dist/apps/AppService.js +21 -0
  46. package/dist/apps/Apps.d.ts +59 -0
  47. package/dist/apps/Apps.js +566 -0
  48. package/dist/apps/appsPlugin.d.ts +3 -0
  49. package/dist/apps/appsPlugin.js +36 -0
  50. package/dist/apps/commands/disableApp.d.ts +2 -0
  51. package/dist/apps/commands/disableApp.js +5 -0
  52. package/dist/apps/commands/enableApp.d.ts +2 -0
  53. package/dist/apps/commands/enableApp.js +5 -0
  54. package/dist/apps/commands/index.d.ts +10 -0
  55. package/dist/apps/commands/index.js +27 -0
  56. package/dist/apps/commands/installApp.d.ts +2 -0
  57. package/dist/apps/commands/installApp.js +5 -0
  58. package/dist/apps/commands/listApps.d.ts +2 -0
  59. package/dist/apps/commands/listApps.js +5 -0
  60. package/dist/apps/commands/makeAppMigration.d.ts +2 -0
  61. package/dist/apps/commands/makeAppMigration.js +9 -0
  62. package/dist/apps/commands/rollbackApp.d.ts +2 -0
  63. package/dist/apps/commands/rollbackApp.js +5 -0
  64. package/dist/apps/commands/uninstallApp.d.ts +2 -0
  65. package/dist/apps/commands/uninstallApp.js +5 -0
  66. package/dist/apps/contracts/AppAction.d.ts +2 -0
  67. package/dist/apps/contracts/AppAction.js +1 -0
  68. package/dist/apps/contracts/AppDefinition.d.ts +45 -0
  69. package/dist/apps/contracts/AppDefinition.js +1 -0
  70. package/dist/apps/contracts/AppDescription.d.ts +32 -0
  71. package/dist/apps/contracts/AppDescription.js +1 -0
  72. package/dist/apps/contracts/AppManifest.d.ts +30 -0
  73. package/dist/apps/contracts/AppManifest.js +1 -0
  74. package/dist/apps/contracts/AppNavigation.d.ts +9 -0
  75. package/dist/apps/contracts/AppNavigation.js +1 -0
  76. package/dist/apps/contracts/AppNavigationBadge.d.ts +6 -0
  77. package/dist/apps/contracts/AppNavigationBadge.js +1 -0
  78. package/dist/apps/contracts/AppNavigationContext.d.ts +8 -0
  79. package/dist/apps/contracts/AppNavigationContext.js +1 -0
  80. package/dist/apps/contracts/AppNavigationResult.d.ts +12 -0
  81. package/dist/apps/contracts/AppNavigationResult.js +1 -0
  82. package/dist/apps/contracts/AppRoute.d.ts +19 -0
  83. package/dist/apps/contracts/AppRoute.js +1 -0
  84. package/dist/apps/contracts/DiscoveredApp.d.ts +10 -0
  85. package/dist/apps/contracts/DiscoveredApp.js +1 -0
  86. package/dist/apps/contracts/InstalledApps.d.ts +3 -0
  87. package/dist/apps/contracts/InstalledApps.js +1 -0
  88. package/dist/apps/contracts/index.d.ts +11 -0
  89. package/dist/apps/contracts/index.js +1 -0
  90. package/dist/apps/defineApp.d.ts +7 -0
  91. package/dist/apps/defineApp.js +8 -0
  92. package/dist/apps/discoverApps.d.ts +3 -0
  93. package/dist/apps/discoverApps.js +62 -0
  94. package/dist/apps/fastify.d.ts +1 -0
  95. package/dist/apps/fastify.js +1 -0
  96. package/dist/apps/index.d.ts +7 -0
  97. package/dist/apps/index.js +7 -0
  98. package/dist/apps/normalizeAppNavigation.d.ts +3 -0
  99. package/dist/apps/normalizeAppNavigation.js +30 -0
  100. package/dist/apps/registerAppRoutes.d.ts +6 -0
  101. package/dist/apps/registerAppRoutes.js +52 -0
  102. package/dist/apps/validateAppDefinitions.d.ts +3 -0
  103. package/dist/apps/validateAppDefinitions.js +65 -0
  104. package/dist/apps/vite.d.ts +1 -0
  105. package/dist/apps/vite.js +1 -0
  106. package/dist/apps/writeAppTypes.d.ts +2 -0
  107. package/dist/apps/writeAppTypes.js +13 -0
  108. package/dist/auth/Auth.d.ts +18 -0
  109. package/dist/auth/Auth.js +89 -13
  110. package/dist/auth/PasswordLoginAttempt.d.ts +50 -0
  111. package/dist/auth/PasswordLoginAttempt.js +60 -0
  112. package/dist/auth/PasswordSuspendedError.d.ts +10 -0
  113. package/dist/auth/PasswordSuspendedError.js +13 -0
  114. package/dist/auth/contracts/PasswordAuthProviderOptions.d.ts +26 -0
  115. package/dist/auth/contracts/PasswordAuthProviderOptions.js +1 -0
  116. package/dist/auth/contracts/PasswordSuspension.d.ts +7 -0
  117. package/dist/auth/contracts/PasswordSuspension.js +1 -0
  118. package/dist/auth/contracts/PasswordSuspensionOptions.d.ts +10 -0
  119. package/dist/auth/contracts/PasswordSuspensionOptions.js +1 -0
  120. package/dist/auth/contracts/index.d.ts +3 -0
  121. package/dist/auth/contracts/index.js +3 -0
  122. package/dist/auth/index.d.ts +2 -0
  123. package/dist/auth/index.js +2 -0
  124. package/dist/auth/providers/PasswordAuthProvider.d.ts +19 -23
  125. package/dist/auth/providers/PasswordAuthProvider.js +96 -8
  126. package/dist/auth/providers/resolveAuthProviders.js +1 -0
  127. package/dist/cli/Cli.d.ts +2 -0
  128. package/dist/cli/Cli.js +8 -0
  129. package/dist/cli/commands/repl.js +2 -1
  130. package/dist/cli/contracts/CliCommand.d.ts +2 -0
  131. package/dist/cli/contracts/CliCommandInfo.d.ts +12 -0
  132. package/dist/cli/contracts/CliCommandInfo.js +1 -0
  133. package/dist/cli/contracts/index.d.ts +1 -0
  134. package/dist/cli/index.d.ts +1 -0
  135. package/dist/cli/index.js +1 -0
  136. package/dist/cli/listDb3Commands.d.ts +8 -0
  137. package/dist/cli/listDb3Commands.js +10 -0
  138. package/dist/cli/runDb3.d.ts +3 -6
  139. package/dist/cli/runDb3.js +5 -59
  140. package/dist/cli/withDb3Cli.d.ts +4 -0
  141. package/dist/cli/withDb3Cli.js +60 -0
  142. package/dist/db/ActiveQueryBuilder.d.ts +8 -0
  143. package/dist/db/ActiveQueryBuilder.js +11 -0
  144. package/dist/db/ActiveRecord.d.ts +6 -0
  145. package/dist/db/ActiveRecord.js +8 -0
  146. package/dist/db/connection.js +14 -2
  147. package/dist/db/fields/TimestampField.d.ts +1 -1
  148. package/dist/db/fields/TimestampField.js +7 -12
  149. package/dist/db/migrations/DatabaseMigrationManager.d.ts +3 -1
  150. package/dist/db/migrations/DatabaseMigrationManager.js +9 -3
  151. package/dist/db/migrations/contracts/DatabaseMigration.d.ts +7 -0
  152. package/dist/db/migrations/index.d.ts +1 -1
  153. package/dist/db/migrations/index.js +1 -1
  154. package/dist/db/migrations/{KnexMigrationRenderer.d.ts → renderKnexMigration.d.ts} +4 -3
  155. package/dist/db/migrations/{KnexMigrationRenderer.js → renderKnexMigration.js} +7 -6
  156. package/dist/flows/FlowCompiler.js +1 -1
  157. package/dist/flows/Flows.js +1 -1
  158. package/dist/flows/index.d.ts +1 -1
  159. package/dist/flows/index.js +1 -1
  160. package/dist/health/Health.d.ts +41 -0
  161. package/dist/health/Health.js +153 -0
  162. package/dist/health/contracts/Health.d.ts +36 -0
  163. package/dist/health/contracts/Health.js +1 -0
  164. package/dist/health/contracts/HealthHttp.d.ts +15 -0
  165. package/dist/health/contracts/HealthHttp.js +1 -0
  166. package/dist/health/contracts/index.d.ts +2 -0
  167. package/dist/health/contracts/index.js +1 -0
  168. package/dist/health/databaseHealthCheck.d.ts +15 -0
  169. package/dist/health/databaseHealthCheck.js +18 -0
  170. package/dist/health/fastify.d.ts +13 -0
  171. package/dist/health/fastify.js +44 -0
  172. package/dist/health/index.d.ts +3 -0
  173. package/dist/health/index.js +2 -0
  174. package/dist/in-app/InApp.d.ts +33 -0
  175. package/dist/in-app/InApp.js +191 -0
  176. package/dist/in-app/InAppError.d.ts +6 -0
  177. package/dist/in-app/InAppError.js +10 -0
  178. package/dist/in-app/InAppRecord.d.ts +36 -0
  179. package/dist/in-app/InAppRecord.js +24 -0
  180. package/dist/in-app/contracts/InAppInbox.d.ts +45 -0
  181. package/dist/in-app/contracts/InAppInbox.js +1 -0
  182. package/dist/in-app/contracts/InAppMessage.d.ts +22 -0
  183. package/dist/in-app/contracts/InAppMessage.js +1 -0
  184. package/dist/in-app/contracts/InAppScope.d.ts +17 -0
  185. package/dist/in-app/contracts/InAppScope.js +1 -0
  186. package/dist/in-app/contracts/index.d.ts +3 -0
  187. package/dist/in-app/contracts/index.js +3 -0
  188. package/dist/in-app/index.d.ts +4 -0
  189. package/dist/in-app/index.js +4 -0
  190. package/dist/in-app/validation.d.ts +21 -0
  191. package/dist/in-app/validation.js +50 -0
  192. package/dist/index.d.ts +2 -14
  193. package/dist/index.js +2 -5
  194. package/dist/logging/DevelopmentConsole.d.ts +42 -0
  195. package/dist/logging/DevelopmentConsole.js +162 -0
  196. package/dist/logging/Log.d.ts +3 -1
  197. package/dist/logging/Log.js +5 -2
  198. package/dist/logging/PrettyLogFormatter.d.ts +16 -0
  199. package/dist/logging/PrettyLogFormatter.js +151 -0
  200. package/dist/logging/acquireDevelopmentConsole.d.ts +6 -0
  201. package/dist/logging/acquireDevelopmentConsole.js +21 -0
  202. package/dist/logging/contracts/DevelopmentConsoleOptions.d.ts +16 -0
  203. package/dist/logging/contracts/DevelopmentConsoleOptions.js +1 -0
  204. package/dist/logging/contracts/EmailLogOptions.d.ts +8 -0
  205. package/dist/logging/contracts/EmailLogOptions.js +1 -0
  206. package/dist/logging/contracts/HttpExchangeMonitorOptions.d.ts +12 -0
  207. package/dist/logging/contracts/HttpExchangeMonitorOptions.js +1 -0
  208. package/dist/logging/contracts/LogTransportOptions.d.ts +19 -0
  209. package/dist/logging/contracts/LogTransportOptions.js +1 -0
  210. package/dist/logging/contracts/LoggingOptions.d.ts +12 -1
  211. package/dist/logging/contracts/index.d.ts +4 -0
  212. package/dist/logging/contracts/index.js +4 -0
  213. package/dist/logging/drivers/PinoLoggerDriver.d.ts +3 -1
  214. package/dist/logging/drivers/PinoLoggerDriver.js +75 -16
  215. package/dist/logging/formatLogEmail.d.ts +4 -0
  216. package/dist/logging/formatLogEmail.js +21 -0
  217. package/dist/logging/highlightQueueMessage.d.ts +11 -0
  218. package/dist/logging/highlightQueueMessage.js +36 -0
  219. package/dist/logging/httpBodyCapture.d.ts +24 -0
  220. package/dist/logging/httpBodyCapture.js +321 -0
  221. package/dist/logging/index.d.ts +2 -0
  222. package/dist/logging/index.js +2 -0
  223. package/dist/logging/redactLogEmail.d.ts +2 -0
  224. package/dist/logging/redactLogEmail.js +12 -0
  225. package/dist/logging/registerHttpExchangeMonitor.d.ts +10 -0
  226. package/dist/logging/registerHttpExchangeMonitor.js +43 -0
  227. package/dist/logging/transports/EmailLogTransport.d.ts +18 -0
  228. package/dist/logging/transports/EmailLogTransport.js +47 -0
  229. package/dist/mail/Mail.d.ts +2 -0
  230. package/dist/mail/Mail.js +3 -0
  231. package/dist/mail/MailDeliveryError.d.ts +9 -0
  232. package/dist/mail/MailDeliveryError.js +16 -0
  233. package/dist/mail/index.d.ts +1 -0
  234. package/dist/mail/index.js +1 -0
  235. package/dist/mail/transports/MailgunTransport.js +2 -0
  236. package/dist/mail/transports/ResendTransport.d.ts +3 -2
  237. package/dist/mail/transports/ResendTransport.js +22 -14
  238. package/dist/media/MediaManager.d.ts +4 -2
  239. package/dist/media/MediaManager.js +40 -8
  240. package/dist/network/BlockedUrlError.d.ts +16 -0
  241. package/dist/network/BlockedUrlError.js +19 -0
  242. package/dist/network/assertPublicUrl.d.ts +22 -0
  243. package/dist/network/assertPublicUrl.js +67 -0
  244. package/dist/network/contracts/GuardedFetch.d.ts +35 -0
  245. package/dist/network/contracts/GuardedFetch.js +1 -0
  246. package/dist/network/contracts/PublicUrlOptions.d.ts +17 -0
  247. package/dist/network/contracts/PublicUrlOptions.js +1 -0
  248. package/dist/network/contracts/index.d.ts +2 -0
  249. package/dist/network/contracts/index.js +2 -0
  250. package/dist/network/guardedFetch.d.ts +29 -0
  251. package/dist/network/guardedFetch.js +133 -0
  252. package/dist/network/index.d.ts +6 -0
  253. package/dist/network/index.js +6 -0
  254. package/dist/network/playwright/GuardedBrowserProxy.d.ts +32 -0
  255. package/dist/network/playwright/GuardedBrowserProxy.js +172 -0
  256. package/dist/network/playwright/contracts/GuardedBrowserContextOptions.d.ts +37 -0
  257. package/dist/network/playwright/contracts/GuardedBrowserContextOptions.js +1 -0
  258. package/dist/network/playwright/contracts/index.d.ts +1 -0
  259. package/dist/network/playwright/contracts/index.js +1 -0
  260. package/dist/network/playwright/index.d.ts +2 -0
  261. package/dist/network/playwright/index.js +2 -0
  262. package/dist/network/playwright/newGuardedBrowserContext.d.ts +21 -0
  263. package/dist/network/playwright/newGuardedBrowserContext.js +86 -0
  264. package/dist/network/privateNetworkAddresses.d.ts +44 -0
  265. package/dist/network/privateNetworkAddresses.js +157 -0
  266. package/dist/network/publicAddressLookup.d.ts +26 -0
  267. package/dist/network/publicAddressLookup.js +42 -0
  268. package/dist/notifications/Notifications.d.ts +27 -0
  269. package/dist/notifications/Notifications.js +99 -0
  270. package/dist/notifications/contracts/Notification.d.ts +56 -0
  271. package/dist/notifications/contracts/Notification.js +1 -0
  272. package/dist/notifications/contracts/NotificationDelivery.d.ts +11 -0
  273. package/dist/notifications/contracts/NotificationDelivery.js +1 -0
  274. package/dist/notifications/contracts/index.d.ts +2 -0
  275. package/dist/notifications/contracts/index.js +2 -0
  276. package/dist/notifications/index.d.ts +2 -0
  277. package/dist/notifications/index.js +2 -0
  278. package/dist/queue/JobRunAttempt.d.ts +16 -0
  279. package/dist/queue/JobRunAttempt.js +17 -0
  280. package/dist/queue/JobRunEvent.d.ts +15 -0
  281. package/dist/queue/JobRunEvent.js +16 -0
  282. package/dist/queue/JobRunStoppedError.d.ts +6 -0
  283. package/dist/queue/JobRunStoppedError.js +10 -0
  284. package/dist/queue/Queue.d.ts +19 -4
  285. package/dist/queue/Queue.js +122 -9
  286. package/dist/queue/QueueTerminalError.d.ts +9 -0
  287. package/dist/queue/QueueTerminalError.js +12 -0
  288. package/dist/queue/QueueWorker.d.ts +12 -5
  289. package/dist/queue/QueueWorker.js +94 -9
  290. package/dist/queue/QueueWorkerReporter.d.ts +17 -0
  291. package/dist/queue/QueueWorkerReporter.js +71 -0
  292. package/dist/queue/QueueableJob.d.ts +2 -2
  293. package/dist/queue/RunnableJob.d.ts +78 -0
  294. package/dist/queue/RunnableJob.js +284 -0
  295. package/dist/queue/console.d.ts +8 -0
  296. package/dist/queue/console.js +53 -19
  297. package/dist/queue/contracts/QueueDriver.d.ts +8 -0
  298. package/dist/queue/contracts/QueueJobRunner.d.ts +4 -0
  299. package/dist/queue/contracts/QueueJobRunner.js +1 -0
  300. package/dist/queue/contracts/QueuePayload.d.ts +1 -1
  301. package/dist/queue/contracts/QueueSelection.d.ts +11 -0
  302. package/dist/queue/contracts/QueueSelection.js +1 -0
  303. package/dist/queue/contracts/QueueService.d.ts +18 -4
  304. package/dist/queue/contracts/QueueWorkerLifecycle.d.ts +2 -2
  305. package/dist/queue/contracts/QueueWorkerSnapshot.d.ts +14 -0
  306. package/dist/queue/contracts/QueueWorkerSnapshot.js +1 -0
  307. package/dist/queue/contracts/QueueableJob.d.ts +7 -3
  308. package/dist/queue/contracts/QueueableJobContract.d.ts +12 -0
  309. package/dist/queue/contracts/QueueableJobContract.js +1 -0
  310. package/dist/queue/contracts/index.d.ts +4 -0
  311. package/dist/queue/contracts/index.js +2 -0
  312. package/dist/queue/drivers/DatabaseQueueDriver.d.ts +4 -0
  313. package/dist/queue/drivers/DatabaseQueueDriver.js +27 -3
  314. package/dist/queue/drivers/RedisQueueDriver.d.ts +7 -0
  315. package/dist/queue/drivers/RedisQueueDriver.js +37 -0
  316. package/dist/queue/index.d.ts +5 -0
  317. package/dist/queue/index.js +5 -0
  318. package/dist/queue/jobEnvelopeHasPrefix.d.ts +3 -0
  319. package/dist/queue/jobEnvelopeHasPrefix.js +4 -0
  320. package/dist/scheduler/ScheduledEvent.d.ts +8 -4
  321. package/dist/scheduler/ScheduledEvent.js +17 -3
  322. package/dist/scheduler/ScheduledJob.d.ts +1 -1
  323. package/dist/scheduler/Scheduler.d.ts +5 -0
  324. package/dist/scheduler/Scheduler.js +92 -28
  325. package/dist/scheduler/SchedulerCheckpointRecord.d.ts +16 -0
  326. package/dist/scheduler/SchedulerCheckpointRecord.js +53 -0
  327. package/dist/scheduler/SchedulerWorker.d.ts +3 -5
  328. package/dist/scheduler/SchedulerWorker.js +58 -14
  329. package/dist/scheduler/console.js +3 -1
  330. package/dist/scheduler/contracts/Schedule.d.ts +19 -0
  331. package/dist/scheduler/contracts/Schedule.js +1 -0
  332. package/dist/scheduler/contracts/Scheduler.d.ts +18 -6
  333. package/dist/scheduler/contracts/SchedulerCheckpoint.d.ts +23 -0
  334. package/dist/scheduler/contracts/SchedulerCheckpoint.js +1 -0
  335. package/dist/scheduler/contracts/SchedulerConsole.d.ts +5 -0
  336. package/dist/scheduler/contracts/SchedulerWorker.d.ts +6 -1
  337. package/dist/scheduler/contracts/index.d.ts +2 -0
  338. package/dist/scheduler/contracts/index.js +2 -0
  339. package/dist/scheduler/index.d.ts +1 -0
  340. package/dist/scheduler/index.js +1 -0
  341. package/dist/server/App.d.ts +36 -4
  342. package/dist/server/App.js +57 -7
  343. package/dist/server/contracts/HttpErrorHandlerOptions.d.ts +29 -0
  344. package/dist/server/contracts/HttpErrorHandlerOptions.js +1 -0
  345. package/dist/server/contracts/index.d.ts +1 -0
  346. package/dist/server/contracts/index.js +1 -0
  347. package/dist/server/index.d.ts +4 -0
  348. package/dist/server/index.js +4 -0
  349. package/dist/server/publicServerErrorMessage.d.ts +11 -0
  350. package/dist/server/publicServerErrorMessage.js +16 -0
  351. package/dist/server/registerBrowserJsonFormatting.d.ts +16 -0
  352. package/dist/server/registerBrowserJsonFormatting.js +100 -0
  353. package/dist/server/registerHttpErrorHandler.d.ts +20 -0
  354. package/dist/server/registerHttpErrorHandler.js +93 -0
  355. package/dist/ssr/vite/contracts/ViteSsrOptions.d.ts +2 -0
  356. package/dist/ssr/vite/fastifyViteSsr.js +4 -3
  357. package/dist/storage/drivers/FlystorageDisk.js +2 -2
  358. package/dist/storage/index.d.ts +2 -2
  359. package/dist/storage/index.js +2 -2
  360. package/dist/websocket/WebSocketChannels.d.ts +18 -0
  361. package/dist/websocket/WebSocketChannels.js +129 -0
  362. package/dist/websocket/WebSocketConnection.d.ts +25 -0
  363. package/dist/websocket/WebSocketConnection.js +244 -0
  364. package/dist/websocket/WebSockets.d.ts +41 -0
  365. package/dist/websocket/WebSockets.js +194 -0
  366. package/dist/websocket/client/WebSocketClient.d.ts +21 -0
  367. package/dist/websocket/client/WebSocketClient.js +230 -0
  368. package/dist/websocket/client/index.d.ts +3 -0
  369. package/dist/websocket/client/index.js +1 -0
  370. package/dist/websocket/contracts/WebSocketChannel.d.ts +20 -0
  371. package/dist/websocket/contracts/WebSocketChannel.js +1 -0
  372. package/dist/websocket/contracts/WebSocketClient.d.ts +45 -0
  373. package/dist/websocket/contracts/WebSocketClient.js +1 -0
  374. package/dist/websocket/contracts/WebSocketEndpoint.d.ts +43 -0
  375. package/dist/websocket/contracts/WebSocketEndpoint.js +1 -0
  376. package/dist/websocket/contracts/WebSocketOptions.d.ts +48 -0
  377. package/dist/websocket/contracts/WebSocketOptions.js +1 -0
  378. package/dist/websocket/contracts/WebSocketPresence.d.ts +6 -0
  379. package/dist/websocket/contracts/WebSocketPresence.js +1 -0
  380. package/dist/websocket/contracts/WebSocketServiceOptions.d.ts +12 -0
  381. package/dist/websocket/contracts/WebSocketServiceOptions.js +1 -0
  382. package/dist/websocket/contracts/index.d.ts +6 -0
  383. package/dist/websocket/contracts/index.js +1 -0
  384. package/dist/websocket/defineChannel.d.ts +8 -0
  385. package/dist/websocket/defineChannel.js +13 -0
  386. package/dist/websocket/defineWebSocket.d.ts +14 -0
  387. package/dist/websocket/defineWebSocket.js +4 -0
  388. package/dist/websocket/fastify.d.ts +11 -0
  389. package/dist/websocket/fastify.js +38 -0
  390. package/dist/websocket/index.d.ts +5 -0
  391. package/dist/websocket/index.js +4 -0
  392. package/package.json +108 -7
  393. package/src/ai/AIErrors.ts +10 -0
  394. package/src/ai/AIFailover.ts +3 -2
  395. package/src/ai/AIProviderAdmission.ts +329 -0
  396. package/src/ai/AIRateLimiter.ts +134 -10
  397. package/src/ai/AIRequestTrackingError.ts +37 -0
  398. package/src/ai/Agent.ts +85 -71
  399. package/src/ai/Ai.ts +104 -48
  400. package/src/ai/OpenAIProviderError.ts +1 -1
  401. package/src/ai/ProviderSseObserver.ts +89 -0
  402. package/src/ai/README.md +216 -11
  403. package/src/ai/aiServiceTier.ts +14 -0
  404. package/src/ai/chunkEmbeddingText.ts +137 -0
  405. package/src/ai/contracts/AI.ts +17 -0
  406. package/src/ai/contracts/AIRequestErrorDiagnostics.ts +12 -0
  407. package/src/ai/contracts/AIServiceTier.ts +2 -0
  408. package/src/ai/contracts/Agent.ts +3 -0
  409. package/src/ai/contracts/EmbeddingTextChunk.ts +26 -0
  410. package/src/ai/contracts/Pricing.ts +7 -1
  411. package/src/ai/contracts/Providers.ts +2 -0
  412. package/src/ai/contracts/index.ts +2 -0
  413. package/src/ai/examples/prepareDocumentEmbeddings.ts +20 -0
  414. package/src/ai/index.ts +9 -2
  415. package/src/ai/{Models.ts → modelPricing.ts} +37 -4
  416. package/src/apps/AppInstallation.ts +25 -0
  417. package/src/apps/AppRouteError.ts +8 -0
  418. package/src/apps/AppService.ts +30 -0
  419. package/src/apps/Apps.ts +508 -0
  420. package/src/apps/README.md +354 -0
  421. package/src/apps/appsPlugin.ts +34 -0
  422. package/src/apps/commands/disableApp.ts +6 -0
  423. package/src/apps/commands/enableApp.ts +6 -0
  424. package/src/apps/commands/index.ts +29 -0
  425. package/src/apps/commands/installApp.ts +6 -0
  426. package/src/apps/commands/listApps.ts +6 -0
  427. package/src/apps/commands/makeAppMigration.ts +9 -0
  428. package/src/apps/commands/rollbackApp.ts +6 -0
  429. package/src/apps/commands/uninstallApp.ts +6 -0
  430. package/src/apps/contracts/AppAction.ts +2 -0
  431. package/src/apps/contracts/AppDefinition.ts +49 -0
  432. package/src/apps/contracts/AppDescription.ts +27 -0
  433. package/src/apps/contracts/AppManifest.ts +32 -0
  434. package/src/apps/contracts/AppNavigation.ts +10 -0
  435. package/src/apps/contracts/AppNavigationBadge.ts +6 -0
  436. package/src/apps/contracts/AppNavigationContext.ts +6 -0
  437. package/src/apps/contracts/AppNavigationResult.ts +9 -0
  438. package/src/apps/contracts/AppRoute.ts +18 -0
  439. package/src/apps/contracts/DiscoveredApp.ts +11 -0
  440. package/src/apps/contracts/InstalledApps.ts +2 -0
  441. package/src/apps/contracts/index.ts +11 -0
  442. package/src/apps/defineApp.ts +10 -0
  443. package/src/apps/discoverApps.ts +56 -0
  444. package/src/apps/fastify.ts +1 -0
  445. package/src/apps/index.ts +7 -0
  446. package/src/apps/normalizeAppNavigation.ts +29 -0
  447. package/src/apps/registerAppRoutes.ts +48 -0
  448. package/src/apps/validateAppDefinitions.ts +52 -0
  449. package/src/apps/vite.ts +1 -0
  450. package/src/apps/writeAppTypes.ts +14 -0
  451. package/src/auth/Auth.ts +89 -23
  452. package/src/auth/PasswordLoginAttempt.ts +72 -0
  453. package/src/auth/PasswordSuspendedError.ts +13 -0
  454. package/src/auth/README.md +94 -4
  455. package/src/auth/contracts/PasswordAuthProviderOptions.ts +30 -0
  456. package/src/auth/contracts/PasswordSuspension.ts +7 -0
  457. package/src/auth/contracts/PasswordSuspensionOptions.ts +10 -0
  458. package/src/auth/contracts/index.ts +3 -0
  459. package/src/auth/examples/runPasswordAuth.ts +6 -6
  460. package/src/auth/index.ts +2 -0
  461. package/src/auth/providers/PasswordAuthProvider.ts +96 -30
  462. package/src/auth/providers/resolveAuthProviders.ts +1 -0
  463. package/src/cli/Cli.ts +9 -0
  464. package/src/cli/README.md +19 -0
  465. package/src/cli/commands/repl.ts +2 -1
  466. package/src/cli/contracts/CliCommand.ts +2 -0
  467. package/src/cli/contracts/CliCommandInfo.ts +13 -0
  468. package/src/cli/contracts/index.ts +1 -0
  469. package/src/cli/index.ts +1 -0
  470. package/src/cli/listDb3Commands.ts +12 -0
  471. package/src/cli/runDb3.ts +5 -51
  472. package/src/cli/withDb3Cli.ts +55 -0
  473. package/src/db/ActiveQueryBuilder.ts +12 -0
  474. package/src/db/ActiveRecord.ts +9 -0
  475. package/src/db/README.md +45 -1
  476. package/src/db/connection.ts +12 -1
  477. package/src/db/examples/FieldNote.ts +7 -13
  478. package/src/db/examples/KnowledgeNote.ts +7 -13
  479. package/src/db/examples/runNoteMigrations.ts +11 -11
  480. package/src/db/fields/TimestampField.ts +8 -17
  481. package/src/db/migrations/DatabaseMigrationManager.ts +12 -4
  482. package/src/db/migrations/contracts/DatabaseMigration.ts +9 -0
  483. package/src/db/migrations/index.ts +1 -1
  484. package/src/db/migrations/{KnexMigrationRenderer.ts → renderKnexMigration.ts} +8 -14
  485. package/src/flows/FlowCompiler.ts +1 -1
  486. package/src/flows/Flows.ts +1 -1
  487. package/src/flows/index.ts +1 -1
  488. package/src/health/Health.ts +163 -0
  489. package/src/health/README.md +46 -0
  490. package/src/health/contracts/Health.ts +47 -0
  491. package/src/health/contracts/HealthHttp.ts +19 -0
  492. package/src/health/contracts/index.ts +2 -0
  493. package/src/health/databaseHealthCheck.ts +21 -0
  494. package/src/health/fastify.ts +49 -0
  495. package/src/health/index.ts +3 -0
  496. package/src/in-app/InApp.ts +173 -0
  497. package/src/in-app/InAppError.ts +8 -0
  498. package/src/in-app/InAppRecord.ts +41 -0
  499. package/src/in-app/README.md +193 -0
  500. package/src/in-app/contracts/InAppInbox.ts +51 -0
  501. package/src/in-app/contracts/InAppMessage.ts +19 -0
  502. package/src/in-app/contracts/InAppScope.ts +12 -0
  503. package/src/in-app/contracts/index.ts +3 -0
  504. package/src/in-app/examples/sendReportReady.ts +14 -0
  505. package/src/in-app/index.ts +4 -0
  506. package/src/in-app/validation.ts +49 -0
  507. package/src/index.ts +2 -22
  508. package/src/logging/DevelopmentConsole.ts +154 -0
  509. package/src/logging/Log.ts +5 -2
  510. package/src/logging/PrettyLogFormatter.ts +165 -0
  511. package/src/logging/README.md +52 -109
  512. package/src/logging/acquireDevelopmentConsole.ts +19 -0
  513. package/src/logging/contracts/DevelopmentConsoleOptions.ts +13 -0
  514. package/src/logging/contracts/EmailLogOptions.ts +9 -0
  515. package/src/logging/contracts/HttpExchangeMonitorOptions.ts +13 -0
  516. package/src/logging/contracts/LogTransportOptions.ts +10 -0
  517. package/src/logging/contracts/LoggingOptions.ts +12 -1
  518. package/src/logging/contracts/index.ts +4 -0
  519. package/src/logging/development/README.md +88 -0
  520. package/src/logging/drivers/PinoLoggerDriver.ts +72 -20
  521. package/src/logging/examples/runDevelopmentLogs.ts +36 -0
  522. package/src/logging/formatLogEmail.ts +24 -0
  523. package/src/logging/highlightQueueMessage.ts +38 -0
  524. package/src/logging/httpBodyCapture.ts +393 -0
  525. package/src/logging/index.ts +2 -0
  526. package/src/logging/redactLogEmail.ts +12 -0
  527. package/src/logging/registerHttpExchangeMonitor.ts +45 -0
  528. package/src/logging/transports/EmailLogTransport.ts +46 -0
  529. package/src/mail/Mail.ts +5 -0
  530. package/src/mail/MailDeliveryError.ts +8 -0
  531. package/src/mail/README.md +11 -1
  532. package/src/mail/index.ts +1 -0
  533. package/src/mail/transports/MailgunTransport.ts +2 -0
  534. package/src/mail/transports/ResendTransport.ts +24 -22
  535. package/src/media/MediaManager.ts +31 -10
  536. package/src/media/README.md +4 -0
  537. package/src/media/examples/runPrivateFiles.ts +2 -2
  538. package/src/network/BlockedUrlError.ts +19 -0
  539. package/src/network/README.md +133 -0
  540. package/src/network/assertPublicUrl.ts +77 -0
  541. package/src/network/contracts/GuardedFetch.ts +40 -0
  542. package/src/network/contracts/PublicUrlOptions.ts +17 -0
  543. package/src/network/contracts/index.ts +2 -0
  544. package/src/network/examples/runGuardedFetch.ts +35 -0
  545. package/src/network/guardedFetch.ts +150 -0
  546. package/src/network/index.ts +6 -0
  547. package/src/network/playwright/GuardedBrowserProxy.ts +172 -0
  548. package/src/network/playwright/contracts/GuardedBrowserContextOptions.ts +43 -0
  549. package/src/network/playwright/contracts/index.ts +1 -0
  550. package/src/network/playwright/index.ts +2 -0
  551. package/src/network/playwright/newGuardedBrowserContext.ts +74 -0
  552. package/src/network/privateNetworkAddresses.ts +166 -0
  553. package/src/network/publicAddressLookup.ts +49 -0
  554. package/src/notifications/Notifications.ts +105 -0
  555. package/src/notifications/README.md +59 -0
  556. package/src/notifications/contracts/Notification.ts +65 -0
  557. package/src/notifications/contracts/NotificationDelivery.ts +11 -0
  558. package/src/notifications/contracts/index.ts +2 -0
  559. package/src/notifications/examples/ReportReadyNotification.ts +31 -0
  560. package/src/notifications/index.ts +2 -0
  561. package/src/queue/JobRunAttempt.ts +17 -0
  562. package/src/queue/JobRunEvent.ts +16 -0
  563. package/src/queue/JobRunStoppedError.ts +8 -0
  564. package/src/queue/Queue.ts +112 -11
  565. package/src/queue/QueueTerminalError.ts +12 -0
  566. package/src/queue/QueueWorker.ts +86 -7
  567. package/src/queue/QueueWorkerReporter.ts +59 -0
  568. package/src/queue/QueueableJob.ts +2 -2
  569. package/src/queue/README.md +142 -1
  570. package/src/queue/RunnableJob.ts +272 -0
  571. package/src/queue/console.ts +54 -21
  572. package/src/queue/contracts/QueueDriver.ts +9 -0
  573. package/src/queue/contracts/QueueJobRunner.ts +4 -0
  574. package/src/queue/contracts/QueuePayload.ts +1 -1
  575. package/src/queue/contracts/QueueSelection.ts +11 -0
  576. package/src/queue/contracts/QueueService.ts +19 -4
  577. package/src/queue/contracts/QueueWorkerLifecycle.ts +2 -2
  578. package/src/queue/contracts/QueueWorkerSnapshot.ts +15 -0
  579. package/src/queue/contracts/QueueableJob.ts +7 -3
  580. package/src/queue/contracts/QueueableJobContract.ts +13 -0
  581. package/src/queue/contracts/index.ts +6 -0
  582. package/src/queue/drivers/DatabaseQueueDriver.ts +25 -3
  583. package/src/queue/drivers/RedisQueueDriver.ts +36 -0
  584. package/src/queue/examples/runQueueSelection.ts +34 -0
  585. package/src/queue/index.ts +7 -0
  586. package/src/queue/jobEnvelopeHasPrefix.ts +6 -0
  587. package/src/scheduler/README.md +50 -9
  588. package/src/scheduler/ScheduledEvent.ts +20 -5
  589. package/src/scheduler/ScheduledJob.ts +1 -1
  590. package/src/scheduler/Scheduler.ts +73 -27
  591. package/src/scheduler/SchedulerCheckpointRecord.ts +51 -0
  592. package/src/scheduler/SchedulerWorker.ts +54 -19
  593. package/src/scheduler/console.ts +3 -1
  594. package/src/scheduler/contracts/Schedule.ts +22 -0
  595. package/src/scheduler/contracts/Scheduler.ts +21 -6
  596. package/src/scheduler/contracts/SchedulerCheckpoint.ts +23 -0
  597. package/src/scheduler/contracts/SchedulerConsole.ts +5 -0
  598. package/src/scheduler/contracts/SchedulerWorker.ts +6 -1
  599. package/src/scheduler/contracts/index.ts +2 -0
  600. package/src/scheduler/examples/runSchedulerWindow.ts +54 -0
  601. package/src/scheduler/index.ts +1 -0
  602. package/src/server/App.ts +73 -10
  603. package/src/server/README.md +95 -2
  604. package/src/server/contracts/HttpErrorHandlerOptions.ts +29 -0
  605. package/src/server/contracts/index.ts +1 -0
  606. package/src/server/examples/createFirstServer.ts +5 -3
  607. package/src/server/index.ts +4 -0
  608. package/src/server/publicServerErrorMessage.ts +17 -0
  609. package/src/server/registerBrowserJsonFormatting.ts +94 -0
  610. package/src/server/registerHttpErrorHandler.ts +96 -0
  611. package/src/ssr/README.md +6 -0
  612. package/src/ssr/vite/contracts/ViteSsrOptions.ts +2 -0
  613. package/src/ssr/vite/fastifyViteSsr.ts +4 -3
  614. package/src/storage/drivers/FlystorageDisk.ts +2 -2
  615. package/src/storage/index.ts +2 -2
  616. package/src/websocket/README.md +458 -0
  617. package/src/websocket/WebSocketChannels.ts +99 -0
  618. package/src/websocket/WebSocketConnection.ts +162 -0
  619. package/src/websocket/WebSockets.ts +157 -0
  620. package/src/websocket/client/WebSocketClient.ts +188 -0
  621. package/src/websocket/client/index.ts +3 -0
  622. package/src/websocket/contracts/WebSocketChannel.ts +23 -0
  623. package/src/websocket/contracts/WebSocketClient.ts +48 -0
  624. package/src/websocket/contracts/WebSocketEndpoint.ts +46 -0
  625. package/src/websocket/contracts/WebSocketOptions.ts +50 -0
  626. package/src/websocket/contracts/WebSocketPresence.ts +6 -0
  627. package/src/websocket/contracts/WebSocketServiceOptions.ts +12 -0
  628. package/src/websocket/contracts/index.ts +6 -0
  629. package/src/websocket/defineChannel.ts +14 -0
  630. package/src/websocket/defineWebSocket.ts +15 -0
  631. package/src/websocket/examples/board/LiveBoard.ts +97 -0
  632. package/src/websocket/examples/board/SummarizeBoardJob.ts +52 -0
  633. package/src/websocket/examples/board/boardSnapshot.ts +16 -0
  634. package/src/websocket/examples/board/createBoardClient.ts +43 -0
  635. package/src/websocket/examples/board/createBoardStore.ts +58 -0
  636. package/src/websocket/examples/board/registerBoardRoutes.ts +31 -0
  637. package/src/websocket/examples/createChannelSync.ts +66 -0
  638. package/src/websocket/examples/deploymentEndpoint.ts +13 -0
  639. package/src/websocket/examples/deploymentSnapshot.ts +36 -0
  640. package/src/websocket/examples/resourceChannels.ts +18 -0
  641. package/src/websocket/examples/userEndpoint.ts +27 -0
  642. package/src/websocket/fastify.ts +39 -0
  643. package/src/websocket/index.ts +5 -0
  644. package/templates/AGENTS.md +33 -2
  645. /package/dist/flows/{FlowValueValidator.d.ts → flowValueValidator.d.ts} +0 -0
  646. /package/dist/flows/{FlowValueValidator.js → flowValueValidator.js} +0 -0
  647. /package/dist/storage/{mime.d.ts → mimeTypeFromPath.d.ts} +0 -0
  648. /package/dist/storage/{mime.js → mimeTypeFromPath.js} +0 -0
  649. /package/dist/storage/{contents.d.ts → storageContentsToBuffer.d.ts} +0 -0
  650. /package/dist/storage/{contents.js → storageContentsToBuffer.js} +0 -0
  651. /package/src/flows/{FlowValueValidator.ts → flowValueValidator.ts} +0 -0
  652. /package/src/storage/{mime.ts → mimeTypeFromPath.ts} +0 -0
  653. /package/src/storage/{contents.ts → storageContentsToBuffer.ts} +0 -0
@@ -0,0 +1,194 @@
1
+ import { WebSocketServer } from 'ws';
2
+ import { WebSocketConnection } from './WebSocketConnection.js';
3
+ import { WebSocketChannels } from './WebSocketChannels.js';
4
+ /** App-owned WebSocket endpoints on an existing Node HTTP/S listener. */
5
+ export class WebSockets {
6
+ app;
7
+ options;
8
+ /** Process-local, server-authorized channels. Each delivery rechecks the connection's policy. */
9
+ channels = new WebSocketChannels();
10
+ #close;
11
+ #connections = new Map();
12
+ #presenceListeners = new Map();
13
+ #closed = false;
14
+ /** Configures worker HTTP delivery without opening a connection or starting a polling loop. */
15
+ constructor(app, options = {}) {
16
+ this.app = app;
17
+ this.options = options;
18
+ if (options.publish) {
19
+ const { url, token, timeoutMs = 5000 } = options.publish;
20
+ const target = new URL(url);
21
+ if (!['http:', 'https:'].includes(target.protocol) || target.username || target.password || target.hash || target.search)
22
+ throw new Error('Use a trusted HTTP(S) publishing URL without credentials, query or fragment.');
23
+ if (!/^[A-Za-z0-9_-]{32,256}$/.test(token))
24
+ throw new Error('WebSocket publish token must contain 32 to 256 URL-safe characters.');
25
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0)
26
+ throw new Error('Invalid WebSocket publish timeout.');
27
+ }
28
+ }
29
+ /** Returns a publisher for a concrete authorized resource channel. No client subscription is created. */
30
+ channel(name) {
31
+ if (name.length > 256 || !/^[a-zA-Z0-9_.-]+(?::[a-zA-Z0-9_.-]+)*$/.test(name))
32
+ throw new Error('Invalid channel name.');
33
+ return { publish: async (event, data) => {
34
+ if (!event || event.length > 256)
35
+ throw new Error('Invalid channel event.');
36
+ if (this.#closed)
37
+ throw new Error('WebSocket service is closed.');
38
+ const message = JSON.stringify({ channel: name, event, data });
39
+ if (Buffer.byteLength(message) > 65536)
40
+ throw new Error('WebSocket event exceeds 64 KiB.');
41
+ if (!this.#close && this.options.publish) {
42
+ const { url, token, timeoutMs = 5000 } = this.options.publish;
43
+ const response = await fetch(url, {
44
+ method: 'POST', redirect: 'error', signal: AbortSignal.timeout(timeoutMs),
45
+ headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' }, body: message,
46
+ });
47
+ try {
48
+ if (!response.ok)
49
+ throw new Error(`WebSocket publishing failed (${response.status}).`);
50
+ // HTTP acceptance is not a browser delivery receipt or a remote connection count.
51
+ return 0;
52
+ }
53
+ finally {
54
+ await response.body?.cancel();
55
+ }
56
+ }
57
+ return this.channels.publishEvent(name, event, data);
58
+ } };
59
+ }
60
+ /**
61
+ * Mounts exact-path endpoint actions on one existing HTTP/S server.
62
+ * @param server - Host-owned listener; the service never opens or closes its port.
63
+ * @param options - Allowed origins, controller definitions and resource limits.
64
+ */
65
+ mount(server, options) {
66
+ if (this.#close)
67
+ throw new Error('WebSockets are already mounted.');
68
+ this.#closed = false;
69
+ const origins = new Set(options.origins);
70
+ if (!origins.size || [...origins].some(origin => { try {
71
+ const url = new URL(origin);
72
+ return !['http:', 'https:'].includes(url.protocol) || url.origin !== origin;
73
+ }
74
+ catch {
75
+ return true;
76
+ } }))
77
+ throw new Error('WebSockets require exact HTTP(S) origins.');
78
+ const endpoints = new Map(Object.entries(options.endpoints));
79
+ for (const [path, endpoint] of endpoints) {
80
+ if (!path.startsWith('/') || path.startsWith('//') || /[?#\s]/.test(path) || !endpoint || typeof endpoint !== 'object')
81
+ throw new Error('Invalid WebSocket endpoint.');
82
+ }
83
+ const limits = { maxConnections: 1000, maxPayloadBytes: 65536, maxBufferedBytes: 262144, maxPendingMessages: 16, maxPendingSends: 32, authTimeoutMs: 5000, heartbeatMs: 30000, shutdownTimeoutMs: 3000 };
84
+ for (const key of Object.keys(limits)) {
85
+ const value = options[key] ?? limits[key];
86
+ if (!Number.isSafeInteger(value) || value <= 0)
87
+ throw new Error(`Invalid WebSocket limit: ${key}.`);
88
+ limits[key] = value;
89
+ }
90
+ const connections = this.#connections;
91
+ const sockets = new WebSocketServer({ noServer: true, maxPayload: limits.maxPayloadBytes, perMessageDeflate: false });
92
+ /** Contains reporting failures and keeps credentials out of transport diagnostics. */
93
+ const report = (error) => { try {
94
+ options.onError?.(error);
95
+ }
96
+ catch { /* Reporting cannot break cleanup. */ } };
97
+ let closing;
98
+ /** Handles only owned paths; other upgrade listeners retain ownership of their paths. */
99
+ const upgrade = (request, stream, head) => {
100
+ let pathname;
101
+ try {
102
+ pathname = new URL(request.url ?? '/', 'http://localhost').pathname;
103
+ }
104
+ catch {
105
+ stream.destroy();
106
+ return;
107
+ }
108
+ const endpoint = endpoints.get(pathname);
109
+ if (!endpoint) {
110
+ if (server.listenerCount('upgrade') === 1)
111
+ stream.end('HTTP/1.1 404 Not Found\r\nConnection: close\r\nContent-Length: 0\r\n\r\n');
112
+ return;
113
+ }
114
+ if (closing || !request.headers.origin || !origins.has(request.headers.origin) || connections.size >= limits.maxConnections) {
115
+ stream.end('HTTP/1.1 403 Forbidden\r\nConnection: close\r\nContent-Length: 0\r\n\r\n');
116
+ return;
117
+ }
118
+ sockets.handleUpgrade(request, stream, head, ws => {
119
+ const connection = new WebSocketConnection(ws, request, this.app, endpoint, limits, report, () => {
120
+ for (const listener of this.#presenceListeners.get(pathname) ?? []) {
121
+ try {
122
+ void Promise.resolve(this.app.requestContext.run(listener)).catch(report);
123
+ }
124
+ catch (error) {
125
+ report(error);
126
+ }
127
+ }
128
+ }, options.resolveToken);
129
+ connections.set(connection, pathname);
130
+ void connection.finished().then(() => connections.delete(connection));
131
+ });
132
+ };
133
+ server.on('upgrade', upgrade);
134
+ this.#close = () => closing ??= (async () => {
135
+ const current = [...connections.keys()];
136
+ for (const connection of current)
137
+ connection.stop(1001);
138
+ let timer;
139
+ try {
140
+ await Promise.race([Promise.all(current.map(connection => connection.finished())), new Promise(resolve => { timer = setTimeout(resolve, limits.shutdownTimeoutMs); })]);
141
+ }
142
+ finally {
143
+ clearTimeout(timer);
144
+ for (const connection of current)
145
+ connection.ws.terminate();
146
+ connections.clear();
147
+ this.#presenceListeners.clear();
148
+ this.channels.clear();
149
+ server.off('upgrade', upgrade);
150
+ await new Promise(resolve => sockets.close(() => resolve()));
151
+ this.#close = undefined;
152
+ }
153
+ })();
154
+ }
155
+ /** Stops accepting upgrades and bounds socket/application cleanup; safe to call repeatedly. */
156
+ async close() { this.#closed = true; await this.#close?.(); }
157
+ /**
158
+ * Lists distinct authenticated users connected to an exact endpoint in this process.
159
+ * Application code must authorize disclosure; this is never exposed automatically.
160
+ * Presence is approximate and excludes the other instance during blue/green overlap.
161
+ * @param path - Registered endpoint path, excluding query parameters.
162
+ * @returns Current user IDs and connection counts; no session tokens or profile data.
163
+ */
164
+ presence(path) {
165
+ const users = new Map();
166
+ for (const [connection, endpoint] of this.#connections) {
167
+ const id = connection.userId;
168
+ if (endpoint === path && id)
169
+ users.set(id, (users.get(id) ?? 0) + 1);
170
+ }
171
+ return [...users].map(([userId, connections]) => ({ userId, connections }));
172
+ }
173
+ /**
174
+ * Subscribes to local presence changes on one exact endpoint, without exposing them to browsers.
175
+ * Call presence(path) inside the listener to read current users. The listener has no Auth context
176
+ * and does not serialize asynchronous listeners; connection.send() reauthenticates its recipient.
177
+ * @param path - Exact endpoint whose authenticated connections should be observed.
178
+ * @param listener - Application callback for connect, disconnect or revocation changes.
179
+ * @returns Idempotent unsubscribe callback; register it on the owning connection's abort signal.
180
+ */
181
+ onPresence(path, listener) {
182
+ let listeners = this.#presenceListeners.get(path);
183
+ if (!listeners) {
184
+ listeners = new Set();
185
+ this.#presenceListeners.set(path, listeners);
186
+ }
187
+ listeners.add(listener);
188
+ return () => {
189
+ listeners.delete(listener);
190
+ if (!listeners.size && this.#presenceListeners.get(path) === listeners)
191
+ this.#presenceListeners.delete(path);
192
+ };
193
+ }
194
+ }
@@ -0,0 +1,21 @@
1
+ import type { WebSocketClientOptions, WebSocketClientState, WebSocketClientChannel } from '../contracts/WebSocketClient.js';
2
+ /** Browser-safe JSON transport with generation fencing, bounded reconnect and no offline message queue. */
3
+ export declare class WebSocketClient {
4
+ #private;
5
+ /** Validates configuration without opening a connection, allowing safe SSR imports. */
6
+ constructor(options: WebSocketClientOptions);
7
+ /** Current transport state; connected is set only after the server accepts the endpoint handshake. */
8
+ get state(): WebSocketClientState;
9
+ /** Starts once, or explicitly retries after credentials/policy have been repaired. */
10
+ connect(): void;
11
+ /** Closes the socket, cancels reconnect and fences late token/network results. */
12
+ close(): void;
13
+ /** Sends JSON only while connected; rejected messages are never queued or replayed. */
14
+ send(data: unknown): boolean;
15
+ /**
16
+ * Returns a logical channel sharing this client's physical connection.
17
+ * The first listener subscribes; removing the final listener unsubscribes.
18
+ * @param name - Concrete resource channel; the server must independently authorize it.
19
+ */
20
+ channel(name: string): WebSocketClientChannel;
21
+ }
@@ -0,0 +1,230 @@
1
+ /** Browser-safe JSON transport with generation fencing, bounded reconnect and no offline message queue. */
2
+ export class WebSocketClient {
3
+ #subscriptionQueue = [];
4
+ #subscribing;
5
+ #channels = new Map();
6
+ #state = 'closed';
7
+ #socket;
8
+ #generation = 0;
9
+ #attempt = 0;
10
+ #stopped = true;
11
+ #retry;
12
+ #deadline;
13
+ #options;
14
+ /** Validates configuration without opening a connection, allowing safe SSR imports. */
15
+ constructor(options) {
16
+ const url = new URL(options.url);
17
+ if (!['ws:', 'wss:'].includes(url.protocol) || url.username || url.password || url.hash)
18
+ throw new Error('Use an absolute ws(s) URL without credentials or fragment.');
19
+ this.#options = { maxReconnectDelayMs: 30000, connectTimeoutMs: 10000, maxBufferedBytes: 65536, ...options };
20
+ for (const key of ['maxReconnectDelayMs', 'connectTimeoutMs', 'maxBufferedBytes']) {
21
+ if (!Number.isSafeInteger(this.#options[key]) || this.#options[key] <= 0)
22
+ throw new Error(`Invalid WebSocket client option: ${key}.`);
23
+ }
24
+ }
25
+ /** Current transport state; connected is set only after the server accepts the endpoint handshake. */
26
+ get state() { return this.#state; }
27
+ /** Starts once, or explicitly retries after credentials/policy have been repaired. */
28
+ connect() {
29
+ if (!this.#stopped)
30
+ return;
31
+ this.#stopped = false;
32
+ this.#attempt = 0;
33
+ void this.#open();
34
+ }
35
+ /** Closes the socket, cancels reconnect and fences late token/network results. */
36
+ close() {
37
+ this.#stopped = true;
38
+ this.#generation++;
39
+ clearTimeout(this.#retry);
40
+ clearTimeout(this.#deadline);
41
+ this.#socket?.close(1000);
42
+ this.#socket = undefined;
43
+ this.#subscriptionQueue = [];
44
+ this.#subscribing = undefined;
45
+ this.#setState('closed');
46
+ }
47
+ /** Sends JSON only while connected; rejected messages are never queued or replayed. */
48
+ send(data) {
49
+ if (this.#state !== 'connected' || this.#socket?.readyState !== 1 || data === undefined)
50
+ return false;
51
+ const frame = JSON.stringify({ type: 'message', data });
52
+ if (new TextEncoder().encode(frame).length + this.#socket.bufferedAmount > this.#options.maxBufferedBytes)
53
+ return false;
54
+ this.#socket.send(frame);
55
+ return true;
56
+ }
57
+ /**
58
+ * Returns a logical channel sharing this client's physical connection.
59
+ * The first listener subscribes; removing the final listener unsubscribes.
60
+ * @param name - Concrete resource channel; the server must independently authorize it.
61
+ */
62
+ channel(name) {
63
+ if (name.length > 256 || !/^[a-zA-Z0-9_.-]+(?::[a-zA-Z0-9_.-]+)*$/.test(name))
64
+ throw new Error('Invalid channel name.');
65
+ return { on: (event, listener) => {
66
+ if (!event || event.length > 256)
67
+ throw new Error('Invalid channel event.');
68
+ let events = this.#channels.get(name);
69
+ const subscribe = !events;
70
+ if (!events) {
71
+ events = new Map();
72
+ this.#channels.set(name, events);
73
+ }
74
+ let listeners = events.get(event);
75
+ if (!listeners) {
76
+ listeners = new Set();
77
+ events.set(event, listeners);
78
+ }
79
+ // Each registration owns its own cleanup, even when callbacks are identical.
80
+ const callback = (data) => listener(data);
81
+ listeners.add(callback);
82
+ if (subscribe && this.#state === 'connected') {
83
+ this.#subscriptionQueue.push(name);
84
+ this.#subscribeNext();
85
+ }
86
+ return () => {
87
+ if (!listeners.delete(callback))
88
+ return;
89
+ if (!listeners.size)
90
+ events.delete(event);
91
+ if (!events.size) {
92
+ this.#channels.delete(name);
93
+ this.#subscriptionQueue = this.#subscriptionQueue.filter(channel => channel !== name);
94
+ this.send({ type: 'channel.unsubscribe', channel: name });
95
+ }
96
+ };
97
+ } };
98
+ }
99
+ /** Serializes subscriptions so a reconnect cannot flood the server's bounded action queue. */
100
+ #subscribeNext() {
101
+ if (this.#subscribing || this.#state !== 'connected')
102
+ return;
103
+ const channel = this.#subscriptionQueue.shift();
104
+ if (!channel)
105
+ return;
106
+ this.#subscribing = channel;
107
+ if (!this.send({ type: 'channel.subscribe', channel })) {
108
+ this.#subscribing = undefined;
109
+ this.#deny();
110
+ }
111
+ }
112
+ /** Dispatches reserved channel envelopes without exposing them as ordinary application messages. */
113
+ #message(data) {
114
+ if (data && typeof data.channel === 'string' && typeof data.type === 'string' && data.type.startsWith('channel.')) {
115
+ if (['channel.subscribed', 'channel.denied'].includes(data.type) && this.#subscribing === data.channel) {
116
+ this.#subscribing = undefined;
117
+ this.#subscribeNext();
118
+ }
119
+ const events = this.#channels.get(data.channel);
120
+ if (!events)
121
+ return;
122
+ if (data.type === 'channel.subscribed')
123
+ this.#options.onSubscribed?.(data.channel);
124
+ else if (data.type === 'channel.denied')
125
+ this.#options.onChannelDenied?.(data.channel);
126
+ else if (data.type === 'channel.event' && typeof data.event === 'string') {
127
+ for (const listener of [...events.get(data.event) ?? []])
128
+ listener(data.data);
129
+ }
130
+ return;
131
+ }
132
+ this.#options.onMessage?.(data);
133
+ }
134
+ /** Creates one attempt and ignores callbacks from replaced connections. */
135
+ async #open() {
136
+ const generation = ++this.#generation;
137
+ this.#setState(this.#attempt ? 'reconnecting' : 'connecting');
138
+ this.#deadline = setTimeout(() => {
139
+ if (generation !== this.#generation || this.#stopped)
140
+ return;
141
+ this.#generation++;
142
+ this.#socket?.close();
143
+ this.#retryLater();
144
+ }, this.#options.connectTimeoutMs);
145
+ try {
146
+ const auth = this.#options.auth ?? 'required';
147
+ const token = auth === 'required' ? await this.#options.token?.() : null;
148
+ if (generation !== this.#generation || this.#stopped)
149
+ return;
150
+ if (auth === 'required' && !token) {
151
+ this.#deny();
152
+ return;
153
+ }
154
+ const factory = this.#options.createSocket ?? nativeSocket;
155
+ const ws = factory(this.#options.url);
156
+ this.#socket = ws;
157
+ ws.onopen = () => { if (generation === this.#generation && !this.#stopped)
158
+ ws.send(JSON.stringify(auth === 'public' ? { type: 'connect' } : { type: 'authenticate', token })); };
159
+ ws.onmessage = event => {
160
+ if (generation !== this.#generation || this.#stopped)
161
+ return;
162
+ let frame;
163
+ try {
164
+ frame = JSON.parse(String(event.data));
165
+ }
166
+ catch {
167
+ this.#deny();
168
+ return;
169
+ }
170
+ if (frame?.type === 'ready' && this.#state !== 'connected') {
171
+ clearTimeout(this.#deadline);
172
+ this.#attempt = 0;
173
+ this.#subscriptionQueue = [...this.#channels.keys()];
174
+ this.#subscribing = undefined;
175
+ this.#setState('connected');
176
+ this.#subscribeNext();
177
+ }
178
+ else if (frame?.type === 'message' && this.#state === 'connected')
179
+ this.#message(frame.data);
180
+ else
181
+ this.#deny();
182
+ };
183
+ ws.onerror = () => { };
184
+ ws.onclose = event => {
185
+ if (generation !== this.#generation || this.#stopped)
186
+ return;
187
+ this.#generation++;
188
+ clearTimeout(this.#deadline);
189
+ if ([4401, 4403, 1003, 1007, 1008, 1009].includes(event.code))
190
+ this.#deny();
191
+ else
192
+ this.#retryLater();
193
+ };
194
+ }
195
+ catch {
196
+ if (generation !== this.#generation || this.#stopped)
197
+ return;
198
+ clearTimeout(this.#deadline);
199
+ this.#retryLater();
200
+ }
201
+ }
202
+ /** Stops retries on an authentication, policy or protocol failure until explicitly connected again. */
203
+ #deny() { this.close(); this.#setState('denied'); }
204
+ /** Retries transient failures with exponential backoff and jitter after blue/green shutdown. */
205
+ #retryLater() {
206
+ if (this.#stopped)
207
+ return;
208
+ if (this.#options.reconnect === false) {
209
+ this.close();
210
+ return;
211
+ }
212
+ this.#setState('reconnecting');
213
+ const ceiling = Math.min(this.#options.maxReconnectDelayMs, 500 * 2 ** Math.min(this.#attempt++, 16));
214
+ this.#retry = setTimeout(() => void this.#open(), Math.max(1, Math.floor(ceiling * (0.5 + Math.random() * 0.5))));
215
+ }
216
+ /** Notifies state consumers only when the lifecycle actually changes. */
217
+ #setState(state) {
218
+ if (this.#state === state)
219
+ return;
220
+ this.#state = state;
221
+ this.#options.onState?.(state);
222
+ }
223
+ }
224
+ /** Resolves the native browser constructor only when connecting, keeping imports SSR-safe. */
225
+ function nativeSocket(url) {
226
+ const Constructor = globalThis.WebSocket;
227
+ if (!Constructor)
228
+ throw new Error('This runtime needs a WebSocket factory.');
229
+ return new Constructor(url);
230
+ }
@@ -0,0 +1,3 @@
1
+ export { WebSocketClient } from './WebSocketClient.js';
2
+ export type { ClientSocket, WebSocketClientOptions, WebSocketClientState } from '../contracts/WebSocketClient.js';
3
+ export type { WebSocketClientChannel } from '../contracts/WebSocketClient.js';
@@ -0,0 +1 @@
1
+ export { WebSocketClient } from './WebSocketClient.js';
@@ -0,0 +1,20 @@
1
+ import type { WebSocketContext } from './WebSocketEndpoint.js';
2
+ /** Current authenticated context and parameters extracted from a channel name. */
3
+ export type WebSocketChannelContext = Omit<WebSocketContext, 'send' | 'close'> & {
4
+ /** Concrete requested channel, never trusted as proof of access. */
5
+ readonly channel: string;
6
+ /** Colon-delimited parameters matched by the server's definition. */
7
+ readonly params: Readonly<Record<string, string>>;
8
+ };
9
+ /** Application policy for a named resource channel. All subscriptions require authorization. */
10
+ export interface WebSocketChannelDefinition {
11
+ /** Pattern such as website:{websiteId}:jobs. */
12
+ readonly pattern: string;
13
+ /** Pure access check, evaluated on subscription and before every delivery. */
14
+ authorize(context: WebSocketChannelContext): boolean | Promise<boolean>;
15
+ }
16
+ /** Server publisher for a concrete channel, including configured worker-to-API HTTP delivery. */
17
+ export interface WebSocketChannelPublisher {
18
+ /** Returns accepted local sends, or zero after remote HTTP acceptance. Never a browser delivery receipt. */
19
+ publish(event: string, data: unknown): Promise<number>;
20
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ /** Browser-visible lifecycle; connected means accepted under the endpoint's authentication policy. */
2
+ export type WebSocketClientState = 'closed' | 'connecting' | 'connected' | 'reconnecting' | 'denied';
3
+ /** Minimal native browser socket surface, also usable by Node integration clients. */
4
+ export interface ClientSocket {
5
+ readonly readyState: number;
6
+ readonly bufferedAmount: number;
7
+ onopen: ((event: any) => void) | null;
8
+ /** Native implementations have different event types; the client reads only data. */
9
+ onmessage: ((event: any) => void) | null;
10
+ /** Native implementations have different event types; the client reads only code. */
11
+ onclose: ((event: any) => void) | null;
12
+ onerror: ((event: any) => void) | null;
13
+ send(data: string): void;
14
+ close(code?: number): void;
15
+ }
16
+ /** Options for the small JSON client. Incoming application data remains untrusted/unknown. */
17
+ export interface WebSocketClientOptions {
18
+ /** Absolute ws(s) URL. Production applications must use wss. */
19
+ url: string;
20
+ /** Reads the existing bearer session afresh on every connection attempt. Never put it in the URL. */
21
+ token?(): string | null | Promise<string | null>;
22
+ /** Must match the endpoint: required (default), cookie (server token resolver), or public. */
23
+ auth?: 'required' | 'cookie' | 'public';
24
+ onMessage?(data: unknown): void;
25
+ /** Called after each successful subscription, including reconnect; reload durable state here. */
26
+ onSubscribed?(channel: string): void;
27
+ /** Called when a requested channel is unknown, ambiguous, denied or exceeds the subscription limit. */
28
+ onChannelDenied?(channel: string): void;
29
+ onState?(state: WebSocketClientState): void;
30
+ /** Defaults to true; authentication/policy denial and protocol failures never auto-retry. */
31
+ reconnect?: boolean;
32
+ /** Maximum delay between reconnect attempts. Default 30000 ms. */
33
+ maxReconnectDelayMs?: number;
34
+ /** Deadline including token acquisition, socket opening and server authentication. Default 10000 ms. */
35
+ connectTimeoutMs?: number;
36
+ /** Outgoing frame/queue limit. Default 64 KiB. */
37
+ maxBufferedBytes?: number;
38
+ /** Optional native-compatible factory for non-browser runtimes. */
39
+ createSocket?(url: string): ClientSocket;
40
+ }
41
+ /** Browser-side view of one logical channel on a shared connection. */
42
+ export interface WebSocketClientChannel {
43
+ /** Adds a listener and subscribes on first use. Returns idempotent listener cleanup. Payloads require app validation. */
44
+ on(event: string, listener: (data: unknown) => void): () => void;
45
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import type { WebSocketChannelDefinition } from './WebSocketChannel.js';
2
+ import type { IncomingMessage } from 'node:http';
3
+ import type { UserIdentity } from '../../auth/index.js';
4
+ /** An accepted connection. Authenticated sends recheck the session; all sends recheck endpoint policy. */
5
+ export interface WebSocketContext<TUser extends UserIdentity | null = UserIdentity> {
6
+ /** Stable connection identity for application-owned local subscriptions. */
7
+ readonly id: string;
8
+ /** Authenticated account ID, derived from framework Auth rather than client data. */
9
+ readonly userId: TUser extends UserIdentity ? string : null;
10
+ /** Fresh account model for this action. */
11
+ readonly user: TUser;
12
+ /** Original upgrade request; HTTP route hooks do not run for this transport. */
13
+ readonly request: IncomingMessage;
14
+ /** Aborted as soon as the connection closes or shutdown starts. */
15
+ readonly signal: AbortSignal;
16
+ /** Sends JSON after fresh authentication and endpoint policy checks. Optional resource guard uses that same fresh context; false means closed or denied. */
17
+ send(data: unknown, authorize?: (context: Omit<WebSocketContext<TUser>, 'send' | 'close'>) => boolean | Promise<boolean>): Promise<boolean>;
18
+ /** Ends the connection normally. */
19
+ close(): void;
20
+ }
21
+ /** Cleanup metadata; close handlers run without authenticated request context. */
22
+ export interface WebSocketClosed {
23
+ id: string;
24
+ userId: string | null;
25
+ code: number;
26
+ }
27
+ /** Controller-style JSON endpoint. Authentication is required unless public access is explicit. */
28
+ export interface WebSocketEndpoint<TMessage = unknown, TUser extends UserIdentity | null = UserIdentity> {
29
+ /** Authentication is required by default. Public endpoints explicitly opt out and always have null identity. */
30
+ auth?: TUser extends UserIdentity ? 'required' : 'public';
31
+ /** Additional resource/tenant authorization, rerun before each action and send. */
32
+ authorize?(context: Omit<WebSocketContext<TUser>, 'send' | 'close'>): boolean | Promise<boolean>;
33
+ /** Named channel policies on this shared endpoint. Anonymous endpoints cannot subscribe to private channels. */
34
+ channels?: readonly WebSocketChannelDefinition[];
35
+ /** Called once after authentication. May send initial application data. */
36
+ open?(context: WebSocketContext<TUser>): void | Promise<void>;
37
+ /** Validates untrusted JSON. Throwing closes with 1008; omitted messages remain unknown. */
38
+ parse?(data: unknown): TMessage | Promise<TMessage>;
39
+ /** Called sequentially for validated application messages in a fresh Auth context. */
40
+ message?(context: WebSocketContext<TUser>, data: TMessage): void | Promise<void>;
41
+ /** Releases application subscriptions. Must settle promptly and must not send data. */
42
+ close?(context: WebSocketClosed): void | Promise<void>;
43
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ import type { WebSocketEndpoint } from './WebSocketEndpoint.js';
2
+ import type { IncomingMessage } from 'node:http';
3
+ /** Mount configuration for one app-owned HTTP/S server. No additional port is opened. */
4
+ export interface WebSocketOptions {
5
+ /** Optional service-authenticated HTTP publisher registered by the Fastify adapter. */
6
+ publish?: {
7
+ /** Exact private route path on this API; keep it off public reverse-proxy routes. */
8
+ path: string;
9
+ /** Dedicated server-only bearer secret matching worker configuration. */
10
+ token: string;
11
+ };
12
+ /** Exact HTTP(S) origins allowed to upgrade. Missing origins are rejected. */
13
+ origins: readonly string[];
14
+ /** Exact paths to endpoint actions. Query parameters are available on request.url. */
15
+ endpoints: Readonly<Record<string, WebSocketEndpoint<any, any>>>;
16
+ /** Resolves an existing session from the upgrade request, e.g. an HttpOnly cookie. Origin checks still apply. Public endpoints never invoke this. */
17
+ resolveToken?(request: IncomingMessage): string | null | Promise<string | null>;
18
+ /** Maximum simultaneous sockets, including unauthenticated handshakes. Default 1000. */
19
+ maxConnections?: number;
20
+ /** Incoming and outgoing JSON frame limit in bytes. Default 64 KiB. */
21
+ maxPayloadBytes?: number;
22
+ /** Maximum queued outgoing bytes per client. Default 256 KiB. */
23
+ maxBufferedBytes?: number;
24
+ /** Maximum queued incoming actions per client. Default 16. */
25
+ maxPendingMessages?: number;
26
+ /** Maximum concurrent outgoing sends awaiting access checks per client. Overflow closes with retryable 1013. Default 32. */
27
+ maxPendingSends?: number;
28
+ /** Deadline for initial authentication. Default 5000 ms. */
29
+ authTimeoutMs?: number;
30
+ /** Ping and session/policy revalidation interval. Default 30000 ms. */
31
+ heartbeatMs?: number;
32
+ /** Bounded wait for connection cleanup at shutdown. Default 3000 ms. */
33
+ shutdownTimeoutMs?: number;
34
+ /** Server-only error reporting. Never receives authentication frames or raw tokens. */
35
+ onError?(error: unknown): void;
36
+ }
37
+ /** Validated internal limits shared by the transport and its connections. */
38
+ export interface WebSocketLimits {
39
+ maxConnections: number;
40
+ maxPayloadBytes: number;
41
+ maxBufferedBytes: number;
42
+ maxPendingMessages: number;
43
+ /** Includes authentication and resource authorization, before socket buffering begins. */
44
+ maxPendingSends: number;
45
+ authTimeoutMs: number;
46
+ heartbeatMs: number;
47
+ shutdownTimeoutMs: number;
48
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ /** Approximate authenticated presence on one endpoint in this API process. */
2
+ export interface WebSocketPresence {
3
+ userId: string;
4
+ /** Multiple tabs/devices for the same account count as separate connections. */
5
+ connections: number;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ /** Optional worker-to-API HTTP delivery; browser connections remain owned by the API. */
2
+ export interface WebSocketServiceOptions {
3
+ /** Used by publishers without a mounted WebSocket server. Mounted APIs deliver locally. */
4
+ publish?: {
5
+ /** Trusted absolute HTTP(S) endpoint; use HTTPS outside a private application network. */
6
+ url: string;
7
+ /** Server-only bearer secret, at least 32 characters. Never expose it to browsers. */
8
+ token: string;
9
+ /** Bounded connection and response deadline. Defaults to 5000 milliseconds. */
10
+ timeoutMs?: number;
11
+ };
12
+ }