sonamu 0.11.16 → 0.13.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 (322) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +1 -2
  2. package/dist/ai/agents/agent.js +2 -3
  3. package/dist/ai/agents/index.js +1 -2
  4. package/dist/ai/index.js +1 -2
  5. package/dist/ai/providers/rtzr/api.js +1 -2
  6. package/dist/ai/providers/rtzr/error.js +2 -3
  7. package/dist/ai/providers/rtzr/model.js +1 -2
  8. package/dist/ai/providers/rtzr/options.js +1 -2
  9. package/dist/ai/providers/rtzr/provider.js +1 -2
  10. package/dist/ai/providers/rtzr/utils.js +1 -2
  11. package/dist/api/base-frame.js +4 -4
  12. package/dist/api/caster.d.ts +1 -1
  13. package/dist/api/caster.d.ts.map +1 -1
  14. package/dist/api/caster.js +9 -9
  15. package/dist/api/code-converters.js +6 -5
  16. package/dist/api/config.d.ts +1 -1
  17. package/dist/api/config.d.ts.map +1 -1
  18. package/dist/api/config.js +2 -3
  19. package/dist/api/context.d.ts +2 -3
  20. package/dist/api/context.d.ts.map +1 -1
  21. package/dist/api/context.js +2 -3
  22. package/dist/api/decorators.js +2 -3
  23. package/dist/api/http-validator.js +2 -3
  24. package/dist/api/index.js +8 -3
  25. package/dist/api/secret.js +1 -2
  26. package/dist/api/sonamu.d.ts +3 -5
  27. package/dist/api/sonamu.d.ts.map +1 -1
  28. package/dist/api/sonamu.js +30 -24
  29. package/dist/api/validator.js +1 -2
  30. package/dist/api/websocket-helpers.js +2 -3
  31. package/dist/auth/audit-log/builders.js +1 -2
  32. package/dist/auth/audit-log/client-ip.js +2 -3
  33. package/dist/auth/audit-log/events.js +1 -2
  34. package/dist/auth/audit-log/plugin.d.ts.map +1 -1
  35. package/dist/auth/audit-log/plugin.js +2 -3
  36. package/dist/auth/audit-log-ingestor.js +2 -3
  37. package/dist/auth/auth-generator.js +2 -3
  38. package/dist/auth/better-auth-entities.js +1 -2
  39. package/dist/auth/better-auth-request.js +2 -3
  40. package/dist/auth/index.js +2 -3
  41. package/dist/auth/knex-adapter.js +2 -3
  42. package/dist/auth/plugins/entity-definitions/admin.js +1 -2
  43. package/dist/auth/plugins/entity-definitions/anonymous.js +1 -2
  44. package/dist/auth/plugins/entity-definitions/api-key.js +1 -2
  45. package/dist/auth/plugins/entity-definitions/audit-log.js +1 -2
  46. package/dist/auth/plugins/entity-definitions/index.js +1 -2
  47. package/dist/auth/plugins/entity-definitions/jwt.js +1 -2
  48. package/dist/auth/plugins/entity-definitions/organization.js +1 -2
  49. package/dist/auth/plugins/entity-definitions/passkey.js +1 -2
  50. package/dist/auth/plugins/entity-definitions/phone-number.js +1 -2
  51. package/dist/auth/plugins/entity-definitions/sso.js +1 -2
  52. package/dist/auth/plugins/entity-definitions/two-factor.js +1 -2
  53. package/dist/auth/plugins/entity-definitions/username.js +1 -2
  54. package/dist/auth/plugins/wrappers/admin.d.ts +33 -32
  55. package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
  56. package/dist/auth/plugins/wrappers/admin.js +2 -3
  57. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  58. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  59. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  60. package/dist/auth/plugins/wrappers/organization.js +2 -3
  61. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  62. package/dist/auth/plugins/wrappers/phone-number.d.ts +43 -1
  63. package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
  64. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  65. package/dist/auth/plugins/wrappers/sso.d.ts +138 -187
  66. package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -1
  67. package/dist/auth/plugins/wrappers/sso.js +1 -2
  68. package/dist/auth/plugins/wrappers/two-factor.d.ts +51 -10
  69. package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
  70. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  71. package/dist/auth/plugins/wrappers/username.d.ts +39 -5
  72. package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
  73. package/dist/auth/plugins/wrappers/username.js +2 -3
  74. package/dist/bin/build-config.js +5 -5
  75. package/dist/bin/compiler-policy.js +2 -3
  76. package/dist/bin/fixture.js +7 -5
  77. package/dist/bin/hmr-hook-register.js +1 -2
  78. package/dist/bin/migrate-targets.js +2 -3
  79. package/dist/bin/test-command.js +2 -3
  80. package/dist/bin/ts-loader-register.js +2 -3
  81. package/dist/bin/ts-loader-registration.js +2 -3
  82. package/dist/bin/typecheck-web.js +2 -3
  83. package/dist/cache/cache-manager.js +1 -2
  84. package/dist/cache/decorator.js +2 -3
  85. package/dist/cache/drivers.js +1 -2
  86. package/dist/cache/index.js +2 -3
  87. package/dist/cache-control/cache-control.js +1 -2
  88. package/dist/code-formatting/index.js +2 -3
  89. package/dist/code-formatting/oxfmt.js +2 -3
  90. package/dist/code-formatting/oxlint.js +2 -3
  91. package/dist/compress/compress.js +1 -2
  92. package/dist/compress/index.js +2 -2
  93. package/dist/compress/types.d.ts +1 -1
  94. package/dist/compress/types.d.ts.map +1 -1
  95. package/dist/cone/cone-generator.js +2 -3
  96. package/dist/database/_batch_update.js +1 -2
  97. package/dist/database/base-model.js +4 -4
  98. package/dist/database/db.js +4 -4
  99. package/dist/database/knex.js +2 -3
  100. package/dist/database/puri-wrapper.js +2 -3
  101. package/dist/database/puri.js +23 -22
  102. package/dist/database/puri.types.js +1 -2
  103. package/dist/database/transaction-context.js +1 -2
  104. package/dist/database/upsert-builder.js +2 -3
  105. package/dist/dict/en.js +2 -3
  106. package/dist/dict/index.js +3 -3
  107. package/dist/dict/ko.js +2 -3
  108. package/dist/dict/rc-keys.js +1 -2
  109. package/dist/dict/sd.js +2 -3
  110. package/dist/dict/sonamu-dictionary.js +7 -6
  111. package/dist/dict/utils.js +2 -3
  112. package/dist/entity/entity-manager.d.ts +66 -66
  113. package/dist/entity/entity-manager.js +4 -4
  114. package/dist/entity/entity-template-cone.js +2 -3
  115. package/dist/entity/entity.js +21 -18
  116. package/dist/env.js +1 -2
  117. package/dist/exceptions/error-handler.d.ts.map +1 -1
  118. package/dist/exceptions/error-handler.js +2 -3
  119. package/dist/exceptions/so-exceptions.js +2 -3
  120. package/dist/filter/index.js +3 -2
  121. package/dist/filter/types.js +1 -2
  122. package/dist/filter/utils.js +7 -6
  123. package/dist/index.d.ts +1 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +42 -6
  126. package/dist/logger/category.js +2 -3
  127. package/dist/logger/configure.js +5 -5
  128. package/dist/migration/code-generation.js +23 -16
  129. package/dist/migration/index-where-predicate.js +2 -3
  130. package/dist/migration/migration-set.js +2 -3
  131. package/dist/migration/migrator.js +2 -3
  132. package/dist/migration/postgresql-schema-reader.js +6 -9
  133. package/dist/migration/slack-confirm.js +2 -3
  134. package/dist/naite/naite-reporter.js +2 -3
  135. package/dist/naite/naite.js +10 -8
  136. package/dist/runtime-type.js +2 -3
  137. package/dist/ssr/hmr-opt-out.js +1 -2
  138. package/dist/ssr/index.js +7 -4
  139. package/dist/ssr/registry.js +1 -2
  140. package/dist/ssr/renderer.js +2 -3
  141. package/dist/storage/base-file.js +1 -2
  142. package/dist/storage/buffered-file.js +2 -3
  143. package/dist/storage/drivers.js +1 -2
  144. package/dist/storage/index.js +2 -3
  145. package/dist/storage/s3-driver.js +1 -2
  146. package/dist/storage/storage-manager.js +2 -3
  147. package/dist/storage/uploaded-file.js +2 -3
  148. package/dist/stream/__tests__/ws-test-helpers.d.ts +108 -0
  149. package/dist/stream/__tests__/ws-test-helpers.d.ts.map +1 -0
  150. package/dist/stream/__tests__/ws-test-helpers.js +259 -0
  151. package/dist/stream/index.d.ts +1 -0
  152. package/dist/stream/index.d.ts.map +1 -1
  153. package/dist/stream/index.js +15 -4
  154. package/dist/stream/sse.js +1 -2
  155. package/dist/stream/ws-audience-resolver.d.ts +8 -5
  156. package/dist/stream/ws-audience-resolver.d.ts.map +1 -1
  157. package/dist/stream/ws-audience-resolver.js +17 -15
  158. package/dist/stream/ws-audience.js +1 -2
  159. package/dist/stream/ws-cluster-bus.d.ts +9 -4
  160. package/dist/stream/ws-cluster-bus.d.ts.map +1 -1
  161. package/dist/stream/ws-cluster-bus.js +2 -3
  162. package/dist/stream/ws-core.d.ts +10 -0
  163. package/dist/stream/ws-core.d.ts.map +1 -1
  164. package/dist/stream/ws-delivery.d.ts +30 -4
  165. package/dist/stream/ws-delivery.d.ts.map +1 -1
  166. package/dist/stream/ws-delivery.js +200 -54
  167. package/dist/stream/ws-frame.d.ts +15 -0
  168. package/dist/stream/ws-frame.d.ts.map +1 -0
  169. package/dist/stream/ws-frame.js +28 -0
  170. package/dist/stream/ws-local-connection-store.d.ts +4 -4
  171. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  172. package/dist/stream/ws-local-connection-store.js +3 -4
  173. package/dist/stream/ws-presence-index.d.ts +36 -0
  174. package/dist/stream/ws-presence-index.d.ts.map +1 -0
  175. package/dist/stream/ws-presence-index.js +176 -0
  176. package/dist/stream/ws-presence-store.d.ts +39 -39
  177. package/dist/stream/ws-presence-store.d.ts.map +1 -1
  178. package/dist/stream/ws-presence-store.js +23 -154
  179. package/dist/stream/ws-registry.d.ts +45 -17
  180. package/dist/stream/ws-registry.d.ts.map +1 -1
  181. package/dist/stream/ws-registry.js +170 -62
  182. package/dist/stream/ws-session-id.d.ts +14 -0
  183. package/dist/stream/ws-session-id.d.ts.map +1 -0
  184. package/dist/stream/ws-session-id.js +36 -0
  185. package/dist/stream/ws-telemetry-memory.js +3 -4
  186. package/dist/stream/ws-telemetry-trace.js +1 -2
  187. package/dist/stream/ws-telemetry.js +2 -3
  188. package/dist/stream/ws.d.ts +20 -10
  189. package/dist/stream/ws.d.ts.map +1 -1
  190. package/dist/stream/ws.js +60 -38
  191. package/dist/syncer/api-parser.js +2 -3
  192. package/dist/syncer/checksum.js +4 -4
  193. package/dist/syncer/code-generator.js +4 -4
  194. package/dist/syncer/entity-operations.js +2 -3
  195. package/dist/syncer/event-batcher.js +1 -2
  196. package/dist/syncer/file-copy.js +2 -3
  197. package/dist/syncer/file-patterns.js +2 -3
  198. package/dist/syncer/file-tracking.js +2 -3
  199. package/dist/syncer/filesystem-dependencies.js +1 -2
  200. package/dist/syncer/index.js +8 -2
  201. package/dist/syncer/module-loader.js +8 -6
  202. package/dist/syncer/syncer-actions.js +8 -7
  203. package/dist/syncer/syncer.js +13 -8
  204. package/dist/syncer/watcher.js +2 -3
  205. package/dist/tasks/decorator.js +1 -2
  206. package/dist/tasks/step-wrapper.js +2 -3
  207. package/dist/tasks/workflow-manager.js +2 -3
  208. package/dist/template/entity-converter.js +17 -16
  209. package/dist/template/helpers.js +2 -3
  210. package/dist/template/implementations/entity.template.js +2 -3
  211. package/dist/template/implementations/entry-server.template.js +2 -3
  212. package/dist/template/implementations/generated.template.js +2 -3
  213. package/dist/template/implementations/generated_http.template.js +6 -6
  214. package/dist/template/implementations/generated_sso.template.js +2 -3
  215. package/dist/template/implementations/http_validators.template.js +2 -3
  216. package/dist/template/implementations/init_types.template.js +2 -3
  217. package/dist/template/implementations/model.template.js +4 -4
  218. package/dist/template/implementations/model_test.template.js +2 -3
  219. package/dist/template/implementations/queries.template.js +2 -3
  220. package/dist/template/implementations/sd.template.js +2 -3
  221. package/dist/template/implementations/services.template.js +2 -3
  222. package/dist/template/implementations/view_form.template.js +12 -9
  223. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  224. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  225. package/dist/template/implementations/view_list.template.js +19 -17
  226. package/dist/template/implementations/view_search_input.template.js +2 -3
  227. package/dist/template/index.js +9 -3
  228. package/dist/template/template-manager.js +2 -3
  229. package/dist/template/template-types.js +1 -2
  230. package/dist/template/template.js +2 -3
  231. package/dist/template/zod-converter.js +54 -47
  232. package/dist/testing/_relation-graph.js +2 -3
  233. package/dist/testing/bootstrap.js +2 -3
  234. package/dist/testing/data-explorer.js +2 -3
  235. package/dist/testing/dev-test-routes.js +2 -3
  236. package/dist/testing/dev-vitest-manager.js +15 -12
  237. package/dist/testing/faker-mappings.js +1 -2
  238. package/dist/testing/filesystem.js +2 -3
  239. package/dist/testing/fixture-generator.js +2 -3
  240. package/dist/testing/fixture-loader.js +1 -2
  241. package/dist/testing/fixture-manager.js +12 -9
  242. package/dist/testing/global-setup.js +5 -5
  243. package/dist/testing/index.js +6 -3
  244. package/dist/testing/naite-vitest-reporter.js +1 -2
  245. package/dist/testing/parallel-db-manager.js +2 -3
  246. package/dist/testing/vitest-helpers.js +2 -3
  247. package/dist/tooling/__tests__/helpers/sonamu-test-root.js +2 -3
  248. package/dist/tooling/cdd-service.js +1 -2
  249. package/dist/tooling/cli-tooling.js +1 -2
  250. package/dist/tooling/fixture-service.js +1 -2
  251. package/dist/tooling/index.js +1 -2
  252. package/dist/tooling/test-run-client.js +2 -3
  253. package/dist/tsdown.api.config.js +1 -2
  254. package/dist/types/types.js +2 -3
  255. package/dist/ui/ai-api.d.ts.map +1 -1
  256. package/dist/ui/ai-api.js +4 -5
  257. package/dist/ui/ai-client.d.ts +2 -2
  258. package/dist/ui/ai-client.d.ts.map +1 -1
  259. package/dist/ui/ai-client.js +9 -8
  260. package/dist/ui/api.d.ts.map +1 -1
  261. package/dist/ui/api.js +11 -8
  262. package/dist/ui/async-route.js +1 -2
  263. package/dist/ui/cdd-service.js +22 -21
  264. package/dist/ui/migrations-api.js +6 -5
  265. package/dist/ui-web/assets/index-QDMyy31K.js +180 -0
  266. package/dist/ui-web/assets/index-dV7akMFB.css +1 -0
  267. package/dist/ui-web/index.html +2 -2
  268. package/dist/utils/async-utils.js +1 -2
  269. package/dist/utils/class-name.js +1 -2
  270. package/dist/utils/console-util.js +1 -2
  271. package/dist/utils/controller.js +2 -3
  272. package/dist/utils/esm-utils.js +1 -2
  273. package/dist/utils/fs-utils.js +2 -3
  274. package/dist/utils/lodash-able.js +1 -2
  275. package/dist/utils/model.js +1 -2
  276. package/dist/utils/object-utils.js +2 -3
  277. package/dist/utils/path-utils.js +2 -3
  278. package/dist/utils/process-utils.js +2 -3
  279. package/dist/utils/runtime-value.js +1 -2
  280. package/dist/utils/sql-parser.js +2 -3
  281. package/dist/utils/type-utils.js +8 -8
  282. package/dist/utils/utils.js +2 -3
  283. package/dist/utils/zod-error.js +2 -3
  284. package/dist/vector/chunking.js +1 -2
  285. package/dist/vector/config.js +1 -2
  286. package/dist/vector/embedding.js +4 -4
  287. package/package.json +63 -63
  288. package/src/ai/agents/agent.ts +1 -1
  289. package/src/api/__tests__/sonamu.plugins.test.ts +11 -1
  290. package/src/api/__tests__/sonamu.websocket-routes.test.ts +234 -0
  291. package/src/api/__tests__/sonamu.websocket.test.ts +241 -24
  292. package/src/api/config.ts +1 -1
  293. package/src/api/context.ts +2 -8
  294. package/src/api/sonamu.ts +46 -28
  295. package/src/auth/audit-log/plugin.ts +2 -0
  296. package/src/compress/types.ts +1 -1
  297. package/src/exceptions/error-handler.ts +3 -2
  298. package/src/index.ts +1 -0
  299. package/src/stream/__tests__/ws-contracts.test.ts +483 -265
  300. package/src/stream/__tests__/ws-multinode.test.ts +326 -0
  301. package/src/stream/__tests__/ws-registry-async.test.ts +855 -0
  302. package/src/stream/__tests__/ws-test-helpers.ts +360 -0
  303. package/src/stream/__tests__/ws.test.ts +342 -145
  304. package/src/stream/index.ts +1 -0
  305. package/src/stream/ws-audience-resolver.ts +21 -19
  306. package/src/stream/ws-cluster-bus.ts +12 -4
  307. package/src/stream/ws-core.ts +14 -0
  308. package/src/stream/ws-delivery.ts +321 -97
  309. package/src/stream/ws-frame.ts +39 -0
  310. package/src/stream/ws-local-connection-store.ts +10 -9
  311. package/src/stream/ws-presence-index.ts +273 -0
  312. package/src/stream/ws-presence-store.ts +64 -284
  313. package/src/stream/ws-registry.ts +272 -85
  314. package/src/stream/ws-session-id.ts +39 -0
  315. package/src/stream/ws.ts +91 -50
  316. package/src/template/implementations/model.template.ts +3 -3
  317. package/src/template/implementations/view_list.template.ts +12 -13
  318. package/src/ui/ai-api.ts +4 -2
  319. package/src/ui/ai-client.ts +2 -2
  320. package/src/ui/api.ts +58 -62
  321. package/dist/ui-web/assets/index-BMdIyKXS.css +0 -1
  322. package/dist/ui-web/assets/index-LpE8u19O.js +0 -178
package/src/api/sonamu.ts CHANGED
@@ -9,7 +9,12 @@ import { dispose as logtapeDispose } from "@logtape/logtape";
9
9
  import { type Auth, type BetterAuthOptions } from "better-auth";
10
10
  import chalk from "chalk";
11
11
  import { type FSWatcher } from "chokidar";
12
- import { type FastifyInstance, type FastifyReply, type FastifyRequest } from "fastify";
12
+ import {
13
+ type FastifyBaseLogger,
14
+ type FastifyInstance,
15
+ type FastifyReply,
16
+ type FastifyRequest,
17
+ } from "fastify";
13
18
  import mime, { lookup as mimeLookup } from "mime-types";
14
19
  import { type WebSocket } from "ws";
15
20
  import { type ZodObject } from "zod";
@@ -470,14 +475,17 @@ class SonamuClass {
470
475
  const options = this.config.server;
471
476
  const { default: fastify } = await import("fastify");
472
477
  const { getLogTapeFastifyLogger } = await import("@logtape/fastify");
478
+ // Fastify 5는 logger 옵션에 설정 객체만 받고, 로거 인스턴스는 loggerInstance로 넘겨야 한다
479
+ // SAFETY: LogTape 어댑터는 pino 호환 메서드 집합(trace~fatal, silent, child)을 제공하며 Fastify 4에서도 같은 객체를 logger로 넘겨 동작했다.
480
+ const loggerInstance: FastifyBaseLogger | undefined =
481
+ this.config.logging !== false
482
+ ? (getLogTapeFastifyLogger({
483
+ category: this.config.logging?.fastifyCategory ?? ["fastify"],
484
+ }) as FastifyBaseLogger)
485
+ : undefined;
473
486
  const server = fastify({
474
487
  ...options.fastify,
475
- logger:
476
- this.config.logging !== false
477
- ? getLogTapeFastifyLogger({
478
- category: this.config.logging?.fastifyCategory ?? ["fastify"],
479
- })
480
- : undefined,
488
+ loggerInstance,
481
489
  });
482
490
  this.server = server;
483
491
  this.websocketRuntime = new WebSocketRuntime(options.websocket);
@@ -714,13 +722,14 @@ class SonamuClass {
714
722
  // 등록된 API와 일치하지 않는 요청에 대한 fallback입니다.
715
723
  throw new NotFoundException(SD("error.api.notFound"));
716
724
  },
717
- wsHandler: async (connection, request) => {
718
- await this.handleDevWebSocketRequest(connection.socket, request, config);
725
+ wsHandler: async (socket, request) => {
726
+ await this.handleDevWebSocketRequest(socket, request, config);
719
727
  },
720
728
  });
721
729
 
730
+ // HEAD는 위 GET catch-all이 exposeHeadRoutes로 자동 노출하므로 중복 선언하면 Fastify 5가 FST_ERR_DUPLICATED_ROUTE를 던진다
722
731
  server.route({
723
- method: ["HEAD", "POST", "PUT", "DELETE", "PATCH"],
732
+ method: ["POST", "PUT", "DELETE", "PATCH"],
724
733
  url: `${this.config.api.route.prefix}/*`,
725
734
  handler: async (request, reply) => {
726
735
  const handler = await this.handleDevApiRequest(request, config);
@@ -784,13 +793,14 @@ class SonamuClass {
784
793
  }
785
794
  throw new NotFoundException(SD("error.api.notFound"));
786
795
  },
787
- wsHandler: async (connection, request) => {
788
- await this.handleDevWebSocketRequest(connection.socket, request, config);
796
+ wsHandler: async (socket, request) => {
797
+ await this.handleDevWebSocketRequest(socket, request, config);
789
798
  },
790
799
  });
791
800
 
801
+ // HEAD는 위 GET catch-all이 exposeHeadRoutes로 자동 노출하므로 중복 선언하면 Fastify 5가 FST_ERR_DUPLICATED_ROUTE를 던진다
792
802
  server.route({
793
- method: ["HEAD", "POST", "PUT", "DELETE", "PATCH"],
803
+ method: ["POST", "PUT", "DELETE", "PATCH"],
794
804
  url: `${this.config.api.route.prefix}/*`,
795
805
  handler: async (request, reply) => {
796
806
  const result = await this.handleDevApiRequest(request, config);
@@ -1331,6 +1341,16 @@ class SonamuClass {
1331
1341
  this.aotHttpValidatorRegistry = nextAotRegistry;
1332
1342
  this.preparedApis = nextApis;
1333
1343
  this.preparedModels = nextModels;
1344
+
1345
+ // @websocket route의 outEvents를 api.path 키로 route table에 반영한다.
1346
+ // 발행 노드가 route별로 한 번 인코딩한 frame을 원격 노드가 그대로 보내므로, HMR 뒤에도 최신 스키마를 써야 한다
1347
+ this.websocketRuntimeValue?.replaceRoutes(
1348
+ nextApis.flatMap((api) =>
1349
+ api.websocketOptions
1350
+ ? [{ routeKey: api.path, outEvents: api.websocketOptions.outEvents }]
1351
+ : [],
1352
+ ),
1353
+ );
1334
1354
  }
1335
1355
 
1336
1356
  // WS path를 일반 HTTP GET으로 호출한 경우 426 + Upgrade 헤더로 명시적으로 websocket 접속을 유도함
@@ -1370,7 +1390,7 @@ class SonamuClass {
1370
1390
  }
1371
1391
 
1372
1392
  const handler = this.createWebSocketHandler(matchedApi, config);
1373
- await handler({ socket }, request);
1393
+ await handler(socket, request);
1374
1394
  }
1375
1395
 
1376
1396
  // WS route 핸들러의 실행 순서를 고정함:
@@ -1383,15 +1403,10 @@ class SonamuClass {
1383
1403
  }
1384
1404
 
1385
1405
  private createWebSocketHandler(api: ExtendedApi, config: SonamuFastifyConfig) {
1386
- return async (
1387
- connection: {
1388
- socket: WebSocket;
1389
- },
1390
- request: FastifyRequest,
1391
- ): Promise<void> => {
1392
- const socket = connection.socket;
1406
+ // @fastify/websocket 11부터 wsHandler는 connection 래퍼 대신 ws.WebSocket을 직접 전달한다
1407
+ return async (socket: WebSocket, request: FastifyRequest): Promise<void> => {
1393
1408
  let wsContext: WebSocketContext<object, object> | null = null;
1394
- let rawWs: ReturnType<WebSocketRuntime["registerConnection"]> | null = null;
1409
+ let rawWs: Awaited<ReturnType<WebSocketRuntime["registerConnection"]>> | null = null;
1395
1410
  let preRegisterPhase: "guard" | "query" | "register" | "handler" = "guard";
1396
1411
  let traceContext: WebSocketTelemetryConnectionContext = {};
1397
1412
 
@@ -1403,7 +1418,9 @@ class SonamuClass {
1403
1418
  preRegisterPhase = "query";
1404
1419
  const reqBody = await this.parseWebSocketRequestParams(api, request);
1405
1420
  preRegisterPhase = "register";
1406
- rawWs = this.websocketRuntime.registerConnection(socket, {
1421
+ // 등록(store 반영 포함)이 끝난 뒤에 context/guard를 진행한다. 리스너는 등록 중에도 붙어 있어 close를 놓치지 않는다
1422
+ rawWs = await this.websocketRuntime.registerConnection(socket, {
1423
+ routeKey: api.path,
1407
1424
  outEvents: api.websocketOptions!.outEvents,
1408
1425
  inEvents: api.websocketOptions!.inEvents,
1409
1426
  namespace: api.websocketOptions!.namespace,
@@ -1427,7 +1444,8 @@ class SonamuClass {
1427
1444
  });
1428
1445
  });
1429
1446
 
1430
- this.websocketRuntime.activateConnection(rawWs.id);
1447
+ // 활성화가 store에 반영된 뒤 handler를 실행해 handler 안의 publish가 이 연결을 대상으로 잡게 한다
1448
+ await this.websocketRuntime.activateConnection(rawWs.id);
1431
1449
  preRegisterPhase = "handler";
1432
1450
 
1433
1451
  const { ApiParamType } = await import("../types/types");
@@ -1604,16 +1622,16 @@ class SonamuClass {
1604
1622
  return ws.waitForClose();
1605
1623
  },
1606
1624
  join(roomId) {
1607
- ws.join(roomId);
1625
+ return ws.join(roomId);
1608
1626
  },
1609
1627
  leave(roomId) {
1610
- ws.leave(roomId);
1628
+ return ws.leave(roomId);
1611
1629
  },
1612
1630
  setUserId(userId) {
1613
- ws.setUserId(userId);
1631
+ return ws.setUserId(userId);
1614
1632
  },
1615
1633
  clearUserId() {
1616
- ws.clearUserId();
1634
+ return ws.clearUserId();
1617
1635
  },
1618
1636
  };
1619
1637
  }
@@ -85,6 +85,8 @@ const getOrganizationTriggerInfo = (user: { id?: string } | null | undefined): B
85
85
  type BetterAuthRequestCtx = GenericEndpointContext & {
86
86
  context: GenericEndpointContext["context"] & {
87
87
  location?: BuilderLocation | null;
88
+ // after hook에서 dispatch가 채우는 응답값. better-auth 1.6.2x부터 GenericEndpointContext 타입에서 빠졌지만 HookEndpointContext에는 남아 있다.
89
+ returned?: unknown;
88
90
  };
89
91
  };
90
92
 
@@ -14,7 +14,7 @@ export type CompressOptions = {
14
14
  /** 압축을 적용할 최소 바이트 크기 (기본값: 1024) */
15
15
  threshold?: number;
16
16
  /** 사용할 인코딩 우선순위 (기본값: ["br", "gzip", "deflate"]) */
17
- encodings?: ("br" | "gzip" | "deflate" | "identity")[];
17
+ encodings?: ("zstd" | "br" | "gzip" | "deflate" | "identity")[];
18
18
  /** 압축할 Content-Type 필터 */
19
19
  customTypes?: RegExp | ((contentType: string) => boolean);
20
20
  };
@@ -1,4 +1,4 @@
1
- import { type FastifyInstance } from "fastify";
1
+ import { type FastifyError, type FastifyInstance } from "fastify";
2
2
  import type z from "zod";
3
3
 
4
4
  import { isObjectValue, isStringValue } from "../utils/runtime-value";
@@ -19,7 +19,8 @@ function isZodIssuePayload<Value>(payload: Value): payload is Value & z.core.$Zo
19
19
  }
20
20
 
21
21
  export function setupErrorHandler(server: FastifyInstance) {
22
- server.setErrorHandler((error, request, reply) => {
22
+ // Fastify 5는 error 타입 기본값이 unknown이므로 기존 FastifyError 계약을 명시한다
23
+ server.setErrorHandler<FastifyError>((error, request, reply) => {
23
24
  error.statusCode ??= 400;
24
25
 
25
26
  if (isSoException(error) && isZodIssuePayload(error.payload)) {
package/src/index.ts CHANGED
@@ -39,6 +39,7 @@ export * from "./stream/ws-audience";
39
39
  export * from "./stream/ws-cluster-bus";
40
40
  export * from "./stream/ws-core";
41
41
  export * from "./stream/ws-presence-store";
42
+ export * from "./stream/ws-session-id";
42
43
  export * from "./stream/ws";
43
44
  export * from "./stream/ws-registry";
44
45
  export * from "./tasks/decorator";