@plitzi/sdk-server 0.37.2 → 0.37.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/CHANGELOG.md +1170 -0
  2. package/README.md +100 -7
  3. package/dist/actions.d.ts +6 -2
  4. package/dist/actions.js +5 -2
  5. package/dist/adapters/cloudAdapters.js +4 -3
  6. package/dist/adapters/jsonAdapters.js +28 -6
  7. package/dist/adapters/jsonAdapters.test.d.ts +1 -0
  8. package/dist/auth.d.ts +7 -4
  9. package/dist/auth.js +8 -6
  10. package/dist/core/auth/api.d.ts +29 -1
  11. package/dist/core/auth/api.js +47 -13
  12. package/dist/core/auth/createAuth.d.ts +4 -0
  13. package/dist/core/auth/createAuth.js +3 -3
  14. package/dist/core/auth/credentials.d.ts +3 -0
  15. package/dist/core/auth/credentials.js +1 -1
  16. package/dist/core/auth/csrf.d.ts +25 -1
  17. package/dist/core/auth/csrf.js +29 -4
  18. package/dist/core/auth/renewal.d.ts +26 -0
  19. package/dist/core/auth/renewal.js +24 -0
  20. package/dist/core/auth/routes.js +8 -6
  21. package/dist/core/auth/session.d.ts +45 -0
  22. package/dist/core/auth/session.js +47 -1
  23. package/dist/core/auth/sessionActivity.d.ts +11 -0
  24. package/dist/core/auth/sessionActivity.js +14 -0
  25. package/dist/core/auth/throttle.d.ts +15 -0
  26. package/dist/core/auth/throttle.js +29 -1
  27. package/dist/core/auth/totp.d.ts +9 -1
  28. package/dist/core/auth/totp.js +11 -6
  29. package/dist/core/createServer.actions.test.d.ts +1 -0
  30. package/dist/core/createServer.d.ts +14 -1
  31. package/dist/core/createServer.functions.test.d.ts +1 -0
  32. package/dist/core/createServer.js +22 -12
  33. package/dist/core/fontStore.js +1 -1
  34. package/dist/core/handlers/authRouteHandlers.d.ts +1 -1
  35. package/dist/core/handlers/authRouteHandlers.js +57 -21
  36. package/dist/core/handlers/csrfMiddleware.d.ts +23 -0
  37. package/dist/core/handlers/csrfMiddleware.js +31 -7
  38. package/dist/core/handlers/csrfMiddleware.test.d.ts +1 -0
  39. package/dist/core/handlers/oauthRouteHandlers.js +5 -3
  40. package/dist/core/handlers/socialRouteHandlers.d.ts +1 -1
  41. package/dist/core/handlers/socialRouteHandlers.js +2 -1
  42. package/dist/core/http/dispatcher.d.ts +9 -1
  43. package/dist/core/http/dispatcher.js +38 -11
  44. package/dist/core/http/navigation.d.ts +5 -2
  45. package/dist/core/http/navigation.js +7 -4
  46. package/dist/core/http/socketResponse.d.ts +18 -0
  47. package/dist/core/http/socketResponse.js +59 -0
  48. package/dist/core/http/sse.d.ts +26 -0
  49. package/dist/core/http/sse.js +78 -0
  50. package/dist/core/http/stages/authRoutes.js +3 -1
  51. package/dist/core/http/stages/exchangeRoute.test.d.ts +1 -0
  52. package/dist/core/http/stages/middlewares.d.ts +1 -1
  53. package/dist/core/http/stages/middlewares.js +16 -10
  54. package/dist/core/http/stages/middlewares.test.d.ts +1 -0
  55. package/dist/core/http/stages/oauth.js +2 -2
  56. package/dist/core/http/stages/sessionRenewal.d.ts +16 -0
  57. package/dist/core/http/stages/sessionRenewal.js +81 -0
  58. package/dist/core/http/stages/sessionRenewal.test.d.ts +1 -0
  59. package/dist/core/http/stages/signInRoute.d.ts +2 -0
  60. package/dist/core/http/stages/signInRoute.js +139 -0
  61. package/dist/core/http/stages/signInRoute.test.d.ts +1 -0
  62. package/dist/core/http/types.d.ts +9 -0
  63. package/dist/core/http/webExchange.d.ts +18 -0
  64. package/dist/core/http/webExchange.js +53 -0
  65. package/dist/core/oauth/authorize.js +37 -13
  66. package/dist/core/oauth/consentPage.js +11 -0
  67. package/dist/core/oauth/issueContext.d.ts +14 -0
  68. package/dist/core/oauth/issueContext.js +32 -0
  69. package/dist/core/oauth/records.d.ts +7 -0
  70. package/dist/core/oauth/register.d.ts +2 -0
  71. package/dist/core/oauth/register.js +32 -11
  72. package/dist/core/oauth/register.test.d.ts +1 -0
  73. package/dist/core/oauth/token.js +21 -6
  74. package/dist/core/oauth/token.test.d.ts +1 -0
  75. package/dist/core/requestParser.d.ts +4 -0
  76. package/dist/core/requestParser.js +14 -7
  77. package/dist/core/sdkAssets.js +1 -1
  78. package/dist/core/server/baseServer.d.ts +10 -0
  79. package/dist/core/server/baseServer.js +42 -11
  80. package/dist/core/server/closeOnSignals.js +4 -3
  81. package/dist/core/server/drain.d.ts +18 -0
  82. package/dist/core/server/drain.js +62 -0
  83. package/dist/core/server/drain.test.d.ts +1 -0
  84. package/dist/core/server/fleet/channel.d.ts +103 -0
  85. package/dist/core/server/fleet/channel.js +191 -0
  86. package/dist/core/server/fleet/channel.test.d.ts +1 -0
  87. package/dist/core/server/fleet/fixtures/fleetServer.d.ts +1 -0
  88. package/dist/core/server/fleet/fleet.integration.test.d.ts +1 -0
  89. package/dist/core/server/fleet/link.d.ts +23 -0
  90. package/dist/core/server/fleet/link.js +70 -0
  91. package/dist/core/server/fleet/relay.d.ts +11 -0
  92. package/dist/core/server/fleet/relay.js +104 -0
  93. package/dist/core/server/fleet/relay.test.d.ts +1 -0
  94. package/dist/core/server/fleet/role.d.ts +46 -0
  95. package/dist/core/server/fleet/role.js +59 -0
  96. package/dist/core/server/fleet/role.test.d.ts +1 -0
  97. package/dist/core/server/fleet/stores.d.ts +7 -0
  98. package/dist/core/server/fleet/stores.js +19 -0
  99. package/dist/core/server/fleet/supervisor.d.ts +26 -0
  100. package/dist/core/server/fleet/supervisor.js +108 -0
  101. package/dist/core/server/fleet/supervisor.test.d.ts +1 -0
  102. package/dist/core/server/pageServer.js +34 -5
  103. package/dist/core/services/action.js +10 -2
  104. package/dist/core/services/functionRoutes.d.ts +9 -0
  105. package/dist/core/services/functionRoutes.js +47 -0
  106. package/dist/core/services/realtime.d.ts +8 -0
  107. package/dist/core/services/realtime.js +57 -0
  108. package/dist/core/services/registry.js +6 -2
  109. package/dist/core/staticFiles.js +12 -4
  110. package/dist/core/staticFiles.test.d.ts +1 -0
  111. package/dist/core/transports.d.ts +13 -3
  112. package/dist/core/transports.js +14 -5
  113. package/dist/functions-api.d.ts +281 -0
  114. package/dist/functions.d.ts +19 -0
  115. package/dist/functions.js +5 -0
  116. package/dist/functionsRunner.d.ts +15 -0
  117. package/dist/functionsRunner.js +6 -0
  118. package/dist/handlers.d.ts +2 -2
  119. package/dist/handlers.js +2 -2
  120. package/dist/helpers/atomicFile.d.ts +10 -0
  121. package/dist/helpers/atomicFile.js +33 -0
  122. package/dist/helpers/atomicFile.test.d.ts +1 -0
  123. package/dist/helpers/buildResponseHelpers.js +35 -11
  124. package/dist/helpers/buildServerInfo.js +4 -2
  125. package/dist/helpers/buildServerInfo.test.d.ts +1 -0
  126. package/dist/helpers/cache/CompressedFileCache.d.ts +18 -0
  127. package/dist/helpers/cache/CompressedFileCache.js +44 -0
  128. package/dist/helpers/cache/CompressedFileCache.test.d.ts +1 -0
  129. package/dist/helpers/cache/cacheManager.d.ts +1 -1
  130. package/dist/helpers/cache/cacheManager.js +2 -1
  131. package/dist/helpers/cache/cacheManager.test.d.ts +1 -0
  132. package/dist/helpers/cache/index.d.ts +1 -1
  133. package/dist/helpers/cache/keys.d.ts +15 -1
  134. package/dist/helpers/cache/keys.js +47 -5
  135. package/dist/helpers/cache/serverCaches.d.ts +7 -1
  136. package/dist/helpers/compress.d.ts +3 -1
  137. package/dist/helpers/compress.js +11 -3
  138. package/dist/helpers/hydrationPayload.d.ts +11 -0
  139. package/dist/helpers/hydrationPayload.js +51 -0
  140. package/dist/helpers/hydrationPayload.test.d.ts +1 -0
  141. package/dist/helpers/metrics.d.ts +1 -1
  142. package/dist/helpers/metrics.js +3 -2
  143. package/dist/helpers/outboundGuard.d.ts +14 -6
  144. package/dist/helpers/outboundGuard.js +132 -8
  145. package/dist/helpers/paintedCookie.d.ts +8 -0
  146. package/dist/helpers/paintedCookie.js +13 -0
  147. package/dist/helpers/reportReactBuild.d.ts +9 -0
  148. package/dist/helpers/reportReactBuild.js +18 -0
  149. package/dist/helpers/reportReactBuild.test.d.ts +1 -0
  150. package/dist/helpers/serverLog.d.ts +25 -1
  151. package/dist/helpers/serverLog.js +68 -3
  152. package/dist/helpers/serverLog.test.d.ts +1 -0
  153. package/dist/helpers/wsFrame.d.ts +3 -0
  154. package/dist/helpers/wsFrame.js +5 -0
  155. package/dist/index.d.ts +6 -1
  156. package/dist/index.js +5 -2
  157. package/dist/kernel.d.ts +2 -1
  158. package/dist/kernel.js +3 -2
  159. package/dist/modules/actions/connectorWrite.js +2 -1
  160. package/dist/modules/actions/index.d.ts +29 -10
  161. package/dist/modules/actions/index.js +43 -6
  162. package/dist/modules/actions/jobs/failureStreak.d.ts +17 -0
  163. package/dist/modules/actions/jobs/failureStreak.js +47 -0
  164. package/dist/modules/actions/jobs/failureStreak.test.d.ts +1 -0
  165. package/dist/modules/actions/jobs/index.d.ts +2 -1
  166. package/dist/modules/actions/jobs/index.js +5 -3
  167. package/dist/modules/actions/jobs/memoryQueue.d.ts +3 -0
  168. package/dist/modules/actions/jobs/memoryQueue.js +17 -1
  169. package/dist/modules/actions/jobs/scheduler.d.ts +2 -0
  170. package/dist/modules/actions/jobs/scheduler.js +12 -7
  171. package/dist/modules/actions/jobs/worker.d.ts +3 -1
  172. package/dist/modules/actions/jobs/worker.js +9 -4
  173. package/dist/modules/actions/moduleFor.js +5 -2
  174. package/dist/modules/actions/runtime/errors.d.ts +12 -0
  175. package/dist/modules/actions/runtime/errors.js +16 -1
  176. package/dist/modules/actions/runtime/kvChange.d.ts +27 -0
  177. package/dist/modules/actions/runtime/kvChange.js +23 -0
  178. package/dist/modules/actions/runtime/kvList.d.ts +51 -0
  179. package/dist/modules/actions/runtime/kvList.js +52 -0
  180. package/dist/modules/actions/runtime/kvStore.d.ts +8 -0
  181. package/dist/modules/actions/runtime/kvStore.js +46 -20
  182. package/dist/modules/actions/runtime/memoryKv.d.ts +3 -0
  183. package/dist/modules/actions/runtime/memoryKv.js +19 -1
  184. package/dist/modules/actions/runtime/namespaceKv.d.ts +4 -6
  185. package/dist/modules/actions/runtime/namespaceKv.js +15 -3
  186. package/dist/modules/actions/runtime/namespaceKv.test.d.ts +1 -0
  187. package/dist/modules/actions/runtime/precheck.js +4 -8
  188. package/dist/modules/actions/runtime/rateLimit.d.ts +19 -0
  189. package/dist/modules/actions/runtime/rateLimit.js +19 -0
  190. package/dist/modules/actions/runtime/redisKv.d.ts +27 -0
  191. package/dist/modules/actions/runtime/redisKv.integration.test.d.ts +1 -0
  192. package/dist/modules/actions/runtime/redisKv.js +46 -0
  193. package/dist/modules/actions/runtime/report.js +2 -1
  194. package/dist/modules/actions/runtime/runAction.d.ts +10 -2
  195. package/dist/modules/actions/runtime/runAction.js +52 -116
  196. package/dist/modules/actions/runtime/runLogger.d.ts +5 -0
  197. package/dist/modules/actions/runtime/runLogger.js +8 -2
  198. package/dist/modules/actions/runtime/signing.d.ts +20 -0
  199. package/dist/modules/actions/runtime/signing.js +25 -0
  200. package/dist/modules/actions/runtime/signing.test.d.ts +1 -0
  201. package/dist/modules/actions/runtime/taskContext.d.ts +33 -0
  202. package/dist/modules/actions/runtime/taskContext.js +124 -0
  203. package/dist/modules/actions/tasks/builtins.js +5 -1
  204. package/dist/modules/actions/tasks/flow.js +81 -10
  205. package/dist/modules/actions/tasks/helpers.js +2 -2
  206. package/dist/modules/actions/tasks/http.js +2 -3
  207. package/dist/modules/actions/tasks/kv.js +39 -0
  208. package/dist/modules/actions/tasks/list.d.ts +2 -0
  209. package/dist/modules/actions/tasks/list.js +145 -0
  210. package/dist/modules/actions/tasks/realtime.d.ts +2 -0
  211. package/dist/modules/actions/tasks/realtime.js +104 -0
  212. package/dist/modules/actions/tasks/registry.d.ts +10 -1
  213. package/dist/modules/actions/tasks/registry.js +17 -6
  214. package/dist/modules/actions/transport/callHandler.js +5 -2
  215. package/dist/modules/actions/transport/catalogHandler.d.ts +5 -2
  216. package/dist/modules/actions/transport/catalogHandler.js +3 -2
  217. package/dist/modules/actions/transport/stream.d.ts +4 -5
  218. package/dist/modules/actions/transport/stream.js +12 -76
  219. package/dist/modules/actions/transport/webhookHandler.js +4 -3
  220. package/dist/modules/actions/types.d.ts +86 -3
  221. package/dist/modules/connectors/engine.js +3 -5
  222. package/dist/modules/functions/build.d.ts +22 -0
  223. package/dist/modules/functions/build.js +122 -0
  224. package/dist/modules/functions/build.test.d.ts +1 -0
  225. package/dist/modules/functions/capabilities.d.ts +22 -0
  226. package/dist/modules/functions/capabilities.js +228 -0
  227. package/dist/modules/functions/config.d.ts +34 -0
  228. package/dist/modules/functions/config.js +24 -0
  229. package/dist/modules/functions/context.d.ts +17 -0
  230. package/dist/modules/functions/context.js +88 -0
  231. package/dist/modules/functions/contract.d.ts +121 -0
  232. package/dist/modules/functions/contract.js +9 -0
  233. package/dist/modules/functions/driver.d.ts +36 -0
  234. package/dist/modules/functions/driver.js +150 -0
  235. package/dist/modules/functions/load.d.ts +15 -0
  236. package/dist/modules/functions/load.js +45 -0
  237. package/dist/modules/functions/load.test.d.ts +1 -0
  238. package/dist/modules/functions/local.d.ts +29 -0
  239. package/dist/modules/functions/local.js +61 -0
  240. package/dist/modules/functions/local.test.d.ts +1 -0
  241. package/dist/modules/functions/manifest.d.ts +24 -0
  242. package/dist/modules/functions/manifest.js +163 -0
  243. package/dist/modules/functions/manifest.test.d.ts +1 -0
  244. package/dist/modules/functions/native.d.ts +8 -0
  245. package/dist/modules/functions/native.js +21 -0
  246. package/dist/modules/functions/native.test.d.ts +1 -0
  247. package/dist/modules/functions/protocol.d.ts +216 -0
  248. package/dist/modules/functions/protocol.js +18 -0
  249. package/dist/modules/functions/routes.d.ts +36 -0
  250. package/dist/modules/functions/routes.js +181 -0
  251. package/dist/modules/functions/routes.test.d.ts +1 -0
  252. package/dist/modules/functions/runner/messages.d.ts +5 -0
  253. package/dist/modules/functions/runner/messages.js +188 -0
  254. package/dist/modules/functions/runner/remote.d.ts +19 -0
  255. package/dist/modules/functions/runner/remote.js +116 -0
  256. package/dist/modules/functions/runner/remote.test.d.ts +1 -0
  257. package/dist/modules/functions/runner/service.d.ts +32 -0
  258. package/dist/modules/functions/runner/service.js +209 -0
  259. package/dist/modules/functions/sandbox/guest.d.ts +45 -0
  260. package/dist/modules/functions/sandbox/guest.js +660 -0
  261. package/dist/modules/functions/sandbox/isolate.d.ts +37 -0
  262. package/dist/modules/functions/sandbox/isolate.js +347 -0
  263. package/dist/modules/functions/sandbox/isolate.test.d.ts +1 -0
  264. package/dist/modules/functions/sandbox/prelude.d.ts +2 -0
  265. package/dist/modules/functions/sandbox/prelude.js +49 -0
  266. package/dist/modules/functions/space.d.ts +40 -0
  267. package/dist/modules/functions/space.js +162 -0
  268. package/dist/modules/functions/testing/tasksOf.d.ts +4 -0
  269. package/dist/modules/functions/tryEntry.d.ts +9 -0
  270. package/dist/modules/functions/tryEntry.js +49 -0
  271. package/dist/modules/mongo/kv.js +31 -0
  272. package/dist/modules/mysql/accounts.js +19 -9
  273. package/dist/modules/mysql/index.d.ts +2 -1
  274. package/dist/modules/mysql/jobs/index.d.ts +1 -1
  275. package/dist/modules/mysql/jobs/kv.js +30 -0
  276. package/dist/modules/mysql/jobs/schema.d.ts +9 -0
  277. package/dist/modules/mysql/jobs/schema.js +21 -4
  278. package/dist/modules/mysql/schema.js +25 -0
  279. package/dist/modules/mysql/sessions.d.ts +1 -11
  280. package/dist/modules/mysql/sessions.js +6 -1
  281. package/dist/modules/realtime/declarations.d.ts +11 -0
  282. package/dist/modules/realtime/declarations.js +26 -0
  283. package/dist/modules/realtime/grants.d.ts +23 -0
  284. package/dist/modules/realtime/grants.js +61 -0
  285. package/dist/modules/realtime/handlers.d.ts +74 -0
  286. package/dist/modules/realtime/handlers.js +224 -0
  287. package/dist/modules/realtime/hub.d.ts +62 -0
  288. package/dist/modules/realtime/hub.js +141 -0
  289. package/dist/modules/realtime/index.d.ts +51 -0
  290. package/dist/modules/realtime/index.js +62 -0
  291. package/dist/modules/realtime/memoryPubSub.d.ts +10 -0
  292. package/dist/modules/realtime/memoryPubSub.js +43 -0
  293. package/dist/modules/realtime/realtime.test.d.ts +1 -0
  294. package/dist/modules/realtime/redisPubSub.d.ts +24 -0
  295. package/dist/modules/realtime/redisPubSub.js +36 -0
  296. package/dist/modules/realtime/redisPubSub.test.d.ts +1 -0
  297. package/dist/modules/realtime/socket.d.ts +25 -0
  298. package/dist/modules/realtime/socket.js +122 -0
  299. package/dist/modules/realtime/socket.test.d.ts +1 -0
  300. package/dist/modules/rsc/handler.d.ts +16 -0
  301. package/dist/modules/rsc/handler.js +17 -10
  302. package/dist/modules/rsc/handler.test.d.ts +1 -0
  303. package/dist/modules/rsc/resolveRscData.js +2 -1
  304. package/dist/modules/runtime/bundle.d.ts +24 -0
  305. package/dist/modules/runtime/bundle.js +102 -0
  306. package/dist/modules/runtime/contract.d.ts +37 -0
  307. package/dist/modules/runtime/contract.js +21 -0
  308. package/dist/modules/runtime/entry.test.d.ts +1 -0
  309. package/dist/modules/runtime/host.d.ts +38 -0
  310. package/dist/modules/runtime/host.js +68 -0
  311. package/dist/modules/runtime/inside.d.ts +15 -0
  312. package/dist/modules/runtime/inside.js +47 -0
  313. package/dist/modules/runtime/inside.test.d.ts +1 -0
  314. package/dist/modules/runtime/runner.d.ts +11 -0
  315. package/dist/modules/runtime/runner.js +38 -0
  316. package/dist/modules/runtime/runtime.test.d.ts +1 -0
  317. package/dist/modules/runtime/stages.d.ts +50 -0
  318. package/dist/modules/runtime/stages.js +117 -0
  319. package/dist/modules/ssr/Component.d.ts +3 -1
  320. package/dist/modules/ssr/Component.js +2 -1
  321. package/dist/modules/ssr/handler.js +10 -2
  322. package/dist/modules/ssr/loadPluginComponents.js +2 -1
  323. package/dist/modules/ssr/prepareRender.js +39 -10
  324. package/dist/modules/ssr/preview.d.ts +3 -0
  325. package/dist/modules/ssr/preview.js +17 -7
  326. package/dist/modules/ssr/redirect.test.d.ts +1 -0
  327. package/dist/modules/ssr/registerExternalPlugins.d.ts +6 -1
  328. package/dist/modules/ssr/registerExternalPlugins.js +19 -16
  329. package/dist/modules/ssr/registerExternalPlugins.test.d.ts +1 -0
  330. package/dist/modules/ssr/reportMissingPlugins.d.ts +9 -0
  331. package/dist/modules/ssr/reportMissingPlugins.js +24 -0
  332. package/dist/modules/ssr/reportMissingPlugins.test.d.ts +1 -0
  333. package/dist/modules/ssr/streamBody.d.ts +2 -2
  334. package/dist/modules/ssr/streamBody.js +4 -1
  335. package/dist/modules/ssr/template.js +1 -1
  336. package/dist/modules/ssr/views/template.ejs +8 -5
  337. package/dist/mysql.d.ts +1 -1
  338. package/dist/mysql.js +2 -2
  339. package/dist/oauth.js +2 -2
  340. package/dist/plugins/compile.js +9 -4
  341. package/dist/plugins/copy.js +3 -3
  342. package/dist/plugins/manager.d.ts +35 -3
  343. package/dist/plugins/manager.js +109 -38
  344. package/dist/runtime.d.ts +15 -0
  345. package/dist/runtime.js +7 -0
  346. package/package.json +39 -8
  347. package/skills/plitzi-authoring/SKILL.md +98 -14
  348. package/skills/plitzi-authoring/reference/accessibility.md +111 -0
  349. package/skills/plitzi-authoring/reference/authoring-errors.md +70 -0
  350. package/skills/plitzi-authoring/reference/data-and-visibility.md +84 -18
  351. package/skills/plitzi-authoring/reference/elements-and-styles.md +61 -7
  352. package/skills/plitzi-authoring/reference/flows.md +108 -17
  353. package/skills/plitzi-authoring/reference/lists.md +74 -0
  354. package/skills/plitzi-authoring/reference/performance.md +67 -0
  355. package/skills/plitzi-authoring/reference/plugins.md +167 -0
  356. package/skills/plitzi-authoring/reference/review-checklist.md +19 -2
  357. package/skills/plitzi-authoring/reference/templates.md +67 -27
  358. package/skills/plitzi-authoring/reference/testing.md +72 -5
  359. package/skills/plitzi-authoring/reference/validation.md +73 -0
@@ -0,0 +1,191 @@
1
+ //#region src/core/server/fleet/channel.ts
2
+ var isRecord = (value) => typeof value === "object" && value !== null;
3
+ /** The channel is shared with `node:cluster` and anything else the deployment sends: only these are ours. */
4
+ var isFleetMessage = (value) => {
5
+ if (!isRecord(value)) return false;
6
+ if (value.sdkFleet === "call") return typeof value.id === "number" && typeof value.store === "string" && typeof value.method === "string" && Array.isArray(value.args);
7
+ if (value.sdkFleet === "reply") return typeof value.id === "number" && typeof value.ok === "boolean";
8
+ if (value.sdkFleet === "broadcast") return typeof value.channel === "string";
9
+ return false;
10
+ };
11
+ var hostable = (create, methods) => ({
12
+ create,
13
+ methods: new Set(Object.keys(methods))
14
+ });
15
+ /**
16
+ * The primary's side: the stores it keeps for its workers, answering their calls.
17
+ *
18
+ * A worker names a store `<kind>#<n>` — the n-th of that kind its code built, the same in every worker since they
19
+ * all run the same code — and the primary makes it from the catalogue the first time it is asked. Nothing is made
20
+ * that no worker uses. A call names a method the kind was registered with and nothing else: the channel is not a way
21
+ * to reach whatever the object happens to carry.
22
+ */
23
+ var createStoreHost = (catalogue) => {
24
+ const instances = /* @__PURE__ */ new Map();
25
+ const storeFor = (key) => {
26
+ const existing = instances.get(key);
27
+ if (existing) return existing;
28
+ const kind = key.slice(0, key.lastIndexOf("#"));
29
+ if (!Object.hasOwn(catalogue, kind)) return;
30
+ const { create, methods } = catalogue[kind];
31
+ const made = {
32
+ instance: create(),
33
+ methods
34
+ };
35
+ instances.set(key, made);
36
+ return made;
37
+ };
38
+ const answer = async (call) => {
39
+ const store = storeFor(call.store);
40
+ const method = store?.methods.has(call.method) ? Reflect.get(store.instance, call.method) : void 0;
41
+ if (!store || typeof method !== "function") return {
42
+ sdkFleet: "reply",
43
+ id: call.id,
44
+ ok: false,
45
+ error: `the primary holds no store "${call.store}" with a method "${call.method}"`
46
+ };
47
+ try {
48
+ const value = await Reflect.apply(method, store.instance, call.args);
49
+ return {
50
+ sdkFleet: "reply",
51
+ id: call.id,
52
+ ok: true,
53
+ value
54
+ };
55
+ } catch (error) {
56
+ return {
57
+ sdkFleet: "reply",
58
+ id: call.id,
59
+ ok: false,
60
+ error: error instanceof Error ? error.message : String(error)
61
+ };
62
+ }
63
+ };
64
+ return { answer };
65
+ };
66
+ /** Who in this process hears a broadcast, by channel. A listener that throws is the caller's to report. */
67
+ var createListeners = (onError) => {
68
+ const listeners = /* @__PURE__ */ new Map();
69
+ const listen = (channel, listener) => {
70
+ const set = listeners.get(channel) ?? /* @__PURE__ */ new Set();
71
+ set.add(listener);
72
+ listeners.set(channel, set);
73
+ return () => set.delete(listener);
74
+ };
75
+ const deliver = (channel, payload) => {
76
+ listeners.get(channel)?.forEach((listener) => {
77
+ try {
78
+ listener(payload);
79
+ } catch (error) {
80
+ onError(channel, error);
81
+ }
82
+ });
83
+ };
84
+ return {
85
+ listen,
86
+ deliver
87
+ };
88
+ };
89
+ /**
90
+ * A worker's side: calls to the primary's stores, and broadcasts both ways.
91
+ *
92
+ * `send` may throw — a value that cannot cross the channel, a primary already gone — and the call then fails
93
+ * rather than waiting for an answer that will not come. The same when the channel closes with calls in flight.
94
+ */
95
+ var createFleetClient = (send, deliver) => {
96
+ const pending = /* @__PURE__ */ new Map();
97
+ let nextId = 0;
98
+ let closed = false;
99
+ const call = (store, method, args) => {
100
+ if (closed) return Promise.reject(/* @__PURE__ */ new Error(`[fleet] ${store}.${method}: the primary is gone`));
101
+ nextId += 1;
102
+ const id = nextId;
103
+ return new Promise((resolve, reject) => {
104
+ pending.set(id, {
105
+ resolve,
106
+ reject
107
+ });
108
+ try {
109
+ send({
110
+ sdkFleet: "call",
111
+ id,
112
+ store,
113
+ method,
114
+ args
115
+ });
116
+ } catch (error) {
117
+ pending.delete(id);
118
+ reject(new Error(`[fleet] ${store}.${method} could not be sent to the primary`, { cause: error }));
119
+ }
120
+ });
121
+ };
122
+ /** Every method of the store, each a call to the copy the primary keeps. */
123
+ const remote = (store, methods) => Object.fromEntries(Object.keys(methods).map((method) => [method, (...args) => call(store, method, args)]));
124
+ const broadcast = (channel, payload) => {
125
+ if (!closed) send({
126
+ sdkFleet: "broadcast",
127
+ channel,
128
+ payload
129
+ });
130
+ };
131
+ const receive = (message) => {
132
+ if (message.sdkFleet === "reply") {
133
+ const waiting = pending.get(message.id);
134
+ pending.delete(message.id);
135
+ if (message.ok) waiting?.resolve(message.value);
136
+ else waiting?.reject(/* @__PURE__ */ new Error(`[fleet] ${message.error}`));
137
+ return;
138
+ }
139
+ if (message.sdkFleet === "broadcast") deliver(message.channel, message.payload);
140
+ };
141
+ const close = () => {
142
+ closed = true;
143
+ const waiting = [...pending.values()];
144
+ pending.clear();
145
+ waiting.forEach((entry) => entry.reject(/* @__PURE__ */ new Error("[fleet] the primary is gone")));
146
+ };
147
+ return {
148
+ call,
149
+ remote,
150
+ broadcast,
151
+ receive,
152
+ close
153
+ };
154
+ };
155
+ /**
156
+ * The primary's side of the channel: it answers its workers' calls from the stores it holds, and passes each
157
+ * broadcast on to every process that did not send it — itself included, so a server in the primary hears it too.
158
+ *
159
+ * A peer that went away between a call and its answer is simply not answered: it is not waiting any more.
160
+ */
161
+ var createFleetHub = ({ host, deliver, peers }) => {
162
+ const sendTo = (peer, message) => {
163
+ try {
164
+ peer?.send(message);
165
+ } catch {}
166
+ };
167
+ const broadcast = (channel, payload, except) => {
168
+ peers().filter((peer) => peer.id !== except).forEach((peer) => sendTo(peer, {
169
+ sdkFleet: "broadcast",
170
+ channel,
171
+ payload
172
+ }));
173
+ };
174
+ const receive = async (from, message) => {
175
+ if (message.sdkFleet === "call") {
176
+ const reply = await host.answer(message);
177
+ sendTo(peers().find((peer) => peer.id === from), reply);
178
+ return;
179
+ }
180
+ if (message.sdkFleet === "broadcast") {
181
+ deliver(message.channel, message.payload);
182
+ broadcast(message.channel, message.payload, from);
183
+ }
184
+ };
185
+ return {
186
+ receive,
187
+ broadcast
188
+ };
189
+ };
190
+ //#endregion
191
+ export { createFleetClient, createFleetHub, createListeners, createStoreHost, hostable, isFleetMessage };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { HostedStore, Remote, StoreMethods } from './channel';
2
+ /**
3
+ * This process's end of the fleet channel (`channel.ts`), over `node:cluster` — for a `primary` or a `worker`
4
+ * (`role.ts`). A single server never reaches past `fleetStore`, which answers it nothing.
5
+ */
6
+ /** The stores a single process keeps in memory by default, which the workers of a fleet share (see `stores.ts`). */
7
+ export type FleetStoreName = 'actions.kv' | 'realtime.grants' | 'actions.jobs' | 'ssr.drafts' | 'auth.rateLimit';
8
+ /**
9
+ * The primary's hub: it answers its workers from the stores in `catalogue`, made when first asked for, and passes
10
+ * broadcasts on. Started before the first fork, so no worker can ask before anyone is answering.
11
+ */
12
+ export declare const startHub: (catalogue: Readonly<Record<FleetStoreName, HostedStore>>) => void;
13
+ /**
14
+ * In a worker, the primary's copy of a store a single server keeps in memory, reached over the channel. Anywhere
15
+ * else, nothing — so a call site reads `deployment's ?? fleetStore(…) ?? what a single server has always made`.
16
+ */
17
+ export declare const fleetStore: <T extends object>(name: FleetStoreName, methods: StoreMethods<T>) => Remote<T> | undefined;
18
+ /** A name for one server's broadcasts, the same in the primary and in each of its workers. */
19
+ export declare const channelName: (label: string) => string;
20
+ /** Tells every other process of the fleet. */
21
+ export declare const broadcast: (channel: string, payload: unknown) => void;
22
+ /** Hears what another process of the fleet broadcast on `channel`. */
23
+ export declare const onBroadcast: (channel: string, listener: (payload: unknown) => void) => (() => void);
@@ -0,0 +1,70 @@
1
+ import { serverLog } from "../../../helpers/serverLog.js";
2
+ import { createFleetClient, createFleetHub, createListeners, createStoreHost, isFleetMessage } from "./channel.js";
3
+ import { isFleetWorker } from "./role.js";
4
+ import cluster from "node:cluster";
5
+ //#region src/core/server/fleet/link.ts
6
+ var listeners = createListeners((channel, error) => serverLog.error("fleet", `a broadcast on "${channel}" failed here`, error));
7
+ var client;
8
+ var hub;
9
+ var workerClient = () => {
10
+ if (client) return client;
11
+ const created = createFleetClient((message) => {
12
+ if (!process.send) throw new Error("this worker has no channel to its primary");
13
+ process.send(message);
14
+ }, listeners.deliver);
15
+ process.on("message", (message) => {
16
+ if (isFleetMessage(message)) created.receive(message);
17
+ });
18
+ process.once("disconnect", () => created.close());
19
+ client = created;
20
+ return created;
21
+ };
22
+ /**
23
+ * The primary's hub: it answers its workers from the stores in `catalogue`, made when first asked for, and passes
24
+ * broadcasts on. Started before the first fork, so no worker can ask before anyone is answering.
25
+ */
26
+ var startHub = (catalogue) => {
27
+ if (hub) return;
28
+ const created = createFleetHub({
29
+ host: createStoreHost(catalogue),
30
+ deliver: listeners.deliver,
31
+ peers: () => Object.values(cluster.workers ?? {}).flatMap((worker) => worker?.isConnected() ? [{
32
+ id: worker.id,
33
+ send: (message) => worker.send(message)
34
+ }] : [])
35
+ });
36
+ cluster.on("message", (worker, message) => {
37
+ if (isFleetMessage(message)) created.receive(worker.id, message);
38
+ });
39
+ hub = created;
40
+ };
41
+ /** The n-th of a name this process asked for: the same code asks in the same order in every process of a fleet, so
42
+ * the n-th one is the same one everywhere. Counted only in a fleet — a single server never asks. */
43
+ var seen = /* @__PURE__ */ new Map();
44
+ var nextKey = (name) => {
45
+ const count = seen.get(name) ?? 0;
46
+ seen.set(name, count + 1);
47
+ return `${name}#${count}`;
48
+ };
49
+ /**
50
+ * In a worker, the primary's copy of a store a single server keeps in memory, reached over the channel. Anywhere
51
+ * else, nothing — so a call site reads `deployment's ?? fleetStore(…) ?? what a single server has always made`.
52
+ */
53
+ var fleetStore = (name, methods) => isFleetWorker() ? workerClient().remote(nextKey(name), methods) : void 0;
54
+ /** A name for one server's broadcasts, the same in the primary and in each of its workers. */
55
+ var channelName = (label) => nextKey(label);
56
+ /** Tells every other process of the fleet. */
57
+ var broadcast = (channel, payload) => {
58
+ if (isFleetWorker()) {
59
+ workerClient().broadcast(channel, payload);
60
+ return;
61
+ }
62
+ hub?.broadcast(channel, payload);
63
+ };
64
+ /** Hears what another process of the fleet broadcast on `channel`. */
65
+ var onBroadcast = (channel, listener) => {
66
+ if (isFleetWorker()) workerClient();
67
+ return listeners.listen(channel, listener);
68
+ };
69
+ //#endregion
70
+ export { broadcast, channelName, fleetStore, onBroadcast, startHub };
@@ -0,0 +1,11 @@
1
+ import { CacheManager, PluginRegistry } from '@plitzi/sdk-shared';
2
+ /** `invalidate` answers, and `size` counts, this process's entries: the others answer nothing back. */
3
+ export declare const relayCache: (cache: CacheManager, channel: string) => CacheManager;
4
+ /**
5
+ * A plugin registered or invalidated in one process is registered or forgotten in all of them. The files are
6
+ * shared — the process that invalidated removed them — so the others only drop what they remember (`forget`).
7
+ *
8
+ * A plugin registered with a `component` cannot be sent: a function does not cross between processes. It is
9
+ * registered where it was called, and said so, rather than silently missing from the other workers.
10
+ */
11
+ export declare const relayPlugins: (plugins: PluginRegistry, forget: (name?: string, version?: string) => void, channel: string, label: string) => PluginRegistry;
@@ -0,0 +1,104 @@
1
+ import { serverLog } from "../../../helpers/serverLog.js";
2
+ import { broadcast, onBroadcast } from "./link.js";
3
+ //#region src/core/server/fleet/relay.ts
4
+ /**
5
+ * `server.cache` and `server.plugins` in a fleet, whose workers each keep their own: what one process is told, every
6
+ * other hears. A single server's are handed back unwrapped (`baseServer.ts`). The call that matters is the one that lands on a random worker — a publish webhook, a
7
+ * `/revalidate` endpoint — and without this it would clear one worker's pages and leave the rest serving the old
8
+ * ones until their TTL ran out.
9
+ *
10
+ * Code that runs in every process (a pub/sub subscription made where the server is created) is told N times; what
11
+ * is relayed is safe to apply again, and cheap: it only drops entries from memory.
12
+ */
13
+ var isRecord = (value) => typeof value === "object" && value !== null;
14
+ var PLUGIN_ACTIONS = [
15
+ "copy",
16
+ "compile",
17
+ "download",
18
+ "cdn"
19
+ ];
20
+ var isPluginAction = (value) => PLUGIN_ACTIONS.some((action) => action === value);
21
+ var cacheFilterOf = (value) => {
22
+ if (!isRecord(value)) return {};
23
+ return {
24
+ ...typeof value.spaceId === "number" ? { spaceId: value.spaceId } : {},
25
+ ...typeof value.environment === "string" ? { environment: value.environment } : {},
26
+ ...typeof value.hostname === "string" ? { hostname: value.hostname } : {}
27
+ };
28
+ };
29
+ /** `invalidate` answers, and `size` counts, this process's entries: the others answer nothing back. */
30
+ var relayCache = (cache, channel) => {
31
+ onBroadcast(channel, (payload) => {
32
+ if (!isRecord(payload)) return;
33
+ if (payload.op === "clear") cache.clear();
34
+ else if (payload.op === "invalidate") cache.invalidate(cacheFilterOf(payload.filter));
35
+ });
36
+ return {
37
+ invalidate: (filter) => {
38
+ const count = cache.invalidate(filter);
39
+ broadcast(channel, {
40
+ op: "invalidate",
41
+ filter: filter ?? {}
42
+ });
43
+ return count;
44
+ },
45
+ clear: () => {
46
+ cache.clear();
47
+ broadcast(channel, { op: "clear" });
48
+ },
49
+ get size() {
50
+ return cache.size;
51
+ }
52
+ };
53
+ };
54
+ var pluginSourceOf = (value) => {
55
+ if (!isRecord(value) || typeof value.js !== "string") return;
56
+ return {
57
+ js: value.js,
58
+ ...typeof value.css === "string" ? { css: value.css } : {},
59
+ ...typeof value.version === "string" ? { version: value.version } : {},
60
+ ...isPluginAction(value.action) ? { action: value.action } : {},
61
+ ...isRecord(value.props) ? { props: value.props } : {}
62
+ };
63
+ };
64
+ var optionalString = (value) => typeof value === "string" ? value : void 0;
65
+ /**
66
+ * A plugin registered or invalidated in one process is registered or forgotten in all of them. The files are
67
+ * shared — the process that invalidated removed them — so the others only drop what they remember (`forget`).
68
+ *
69
+ * A plugin registered with a `component` cannot be sent: a function does not cross between processes. It is
70
+ * registered where it was called, and said so, rather than silently missing from the other workers.
71
+ */
72
+ var relayPlugins = (plugins, forget, channel, label) => {
73
+ onBroadcast(channel, (payload) => {
74
+ if (!isRecord(payload)) return;
75
+ if (payload.op === "register" && typeof payload.name === "string") {
76
+ const source = pluginSourceOf(payload.source);
77
+ if (source) plugins.register(payload.name, source);
78
+ } else if (payload.op === "forget") forget(optionalString(payload.name), optionalString(payload.version));
79
+ });
80
+ return {
81
+ register: (name, source) => {
82
+ plugins.register(name, source);
83
+ if ("component" in source) {
84
+ serverLog.warn(label, `plugin "${name}" is a component: only this process has it. Register component plugins where the server is created, so every worker does.`);
85
+ return;
86
+ }
87
+ broadcast(channel, {
88
+ op: "register",
89
+ name,
90
+ source
91
+ });
92
+ },
93
+ invalidate: async (name, version) => {
94
+ await plugins.invalidate(name, version);
95
+ broadcast(channel, {
96
+ op: "forget",
97
+ name,
98
+ version
99
+ });
100
+ }
101
+ };
102
+ };
103
+ //#endregion
104
+ export { relayCache, relayPlugins };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Where a server decides whether it runs as one process or as several — the one fork between the two modes.
3
+ *
4
+ * - `single`: workers off, one asked for, or one core to run on. Everything is what it always was: the stores are
5
+ * this process's own, `server.cache` is its own, nothing listens on a channel and nothing is forked.
6
+ * - `primary`: the process that was started, asked for more than one. It serves nothing: it forks the workers,
7
+ * restarts the ones that die (`supervisor.ts`) and keeps, for all of them, the stores a single process keeps
8
+ * in memory (`stores.ts`).
9
+ * - `worker`: forked by a primary. It serves, and reaches those stores — and tells the other workers what they must
10
+ * hear — over the channel to its primary (`link.ts`).
11
+ *
12
+ * Every other file in this folder serves the last two; the rest of the server asks only `fleetRole`,
13
+ * `runsFleetJobs` and, for a store, `fleetStore` (which answers nothing outside a worker).
14
+ */
15
+ export type WorkersOption = boolean | number | 'auto';
16
+ export type WorkersPlan = {
17
+ /** The processes that will serve. */
18
+ count: number;
19
+ /** What was asked for, when it was more than the cores there are — and so was lowered to them. */
20
+ requested?: number;
21
+ };
22
+ /**
23
+ * How many processes serve the port.
24
+ *
25
+ * On by default in production — one per core the process may use, which `availableParallelism` reads from the
26
+ * container's CPU quota too, so a quarter-core container gets one. Off by default anywhere else: a development server
27
+ * under `--watch` or a debugger, and a test runner that starts servers in its own process, must stay one process.
28
+ * The config wins over `SDK_SERVER_WORKERS`, which wins over the default.
29
+ *
30
+ * A number is a ceiling, not a demand: more processes than cores only take turns on the same cores, each with its
31
+ * own memory, so it is lowered to the cores there are and the plan says it was.
32
+ */
33
+ export declare const resolveWorkers: (option: WorkersOption | undefined, environment?: NodeJS.ProcessEnv, cores?: number) => WorkersPlan;
34
+ /** The environment the primary gives a worker it forks — and the one worker that carries the fleet's jobs. */
35
+ export declare const fleetWorkerEnv: (runsJobs: boolean) => Record<string, string>;
36
+ export declare const isFleetWorker: () => boolean;
37
+ export type FleetRole = 'single' | 'primary' | 'worker';
38
+ export declare const fleetRole: (plan: WorkersPlan) => FleetRole;
39
+ /**
40
+ * Whether this process runs the scheduler and the job consumers.
41
+ *
42
+ * A single server, yes, as it always did. Of a fleet, one worker only: its workers are one replica, and a replica's
43
+ * `jobs` settings — how many run at once, whether it schedules at all — are for the replica, not for each of its
44
+ * processes. The primary hands the role to the replacement of the worker that carried it.
45
+ */
46
+ export declare const runsFleetJobs: () => boolean;
@@ -0,0 +1,59 @@
1
+ import cluster from "node:cluster";
2
+ import { availableParallelism } from "node:os";
3
+ //#region src/core/server/fleet/role.ts
4
+ /** What the deployment's environment says, when its code says nothing: `SDK_SERVER_WORKERS=1`, `=auto`, `=false`. */
5
+ var fromEnvironment = (raw) => {
6
+ if (raw === void 0 || raw.trim() === "") return;
7
+ const value = raw.trim().toLowerCase();
8
+ if (value === "auto" || value === "true") return "auto";
9
+ if (value === "false" || value === "off") return false;
10
+ return Number(value);
11
+ };
12
+ /**
13
+ * How many processes serve the port.
14
+ *
15
+ * On by default in production — one per core the process may use, which `availableParallelism` reads from the
16
+ * container's CPU quota too, so a quarter-core container gets one. Off by default anywhere else: a development server
17
+ * under `--watch` or a debugger, and a test runner that starts servers in its own process, must stay one process.
18
+ * The config wins over `SDK_SERVER_WORKERS`, which wins over the default.
19
+ *
20
+ * A number is a ceiling, not a demand: more processes than cores only take turns on the same cores, each with its
21
+ * own memory, so it is lowered to the cores there are and the plan says it was.
22
+ */
23
+ var resolveWorkers = (option, environment = process.env, cores = availableParallelism()) => {
24
+ const available = Math.max(1, cores);
25
+ const chosen = option ?? fromEnvironment(environment.SDK_SERVER_WORKERS) ?? (environment.NODE_ENV === "production" ? "auto" : false);
26
+ if (chosen === false) return { count: 1 };
27
+ if (chosen === true || chosen === "auto") return { count: available };
28
+ if (!Number.isInteger(chosen) || chosen < 1) throw new Error(`workers must be true, false, 'auto' or a whole number from 1 — got ${String(chosen)}`);
29
+ return chosen > available ? {
30
+ count: available,
31
+ requested: chosen
32
+ } : { count: chosen };
33
+ };
34
+ /**
35
+ * Only a worker a primary of ours forked carries this: a process that is a cluster worker of something else —
36
+ * PM2's cluster mode, a deployment's own `cluster.fork` — is a single server, with nobody to answer its calls.
37
+ */
38
+ var FLEET_ENV = "SDK_SERVER_FLEET";
39
+ var JOBS_ENV = "SDK_SERVER_FLEET_JOBS";
40
+ /** The environment the primary gives a worker it forks — and the one worker that carries the fleet's jobs. */
41
+ var fleetWorkerEnv = (runsJobs) => ({
42
+ [FLEET_ENV]: "1",
43
+ [JOBS_ENV]: runsJobs ? "1" : "0"
44
+ });
45
+ var isFleetWorker = () => cluster.isWorker && process.env[FLEET_ENV] === "1";
46
+ var fleetRole = (plan) => {
47
+ if (isFleetWorker()) return "worker";
48
+ return plan.count > 1 && cluster.isPrimary ? "primary" : "single";
49
+ };
50
+ /**
51
+ * Whether this process runs the scheduler and the job consumers.
52
+ *
53
+ * A single server, yes, as it always did. Of a fleet, one worker only: its workers are one replica, and a replica's
54
+ * `jobs` settings — how many run at once, whether it schedules at all — are for the replica, not for each of its
55
+ * processes. The primary hands the role to the replacement of the worker that carried it.
56
+ */
57
+ var runsFleetJobs = () => !isFleetWorker() || process.env[JOBS_ENV] === "1";
58
+ //#endregion
59
+ export { fleetRole, fleetWorkerEnv, isFleetWorker, resolveWorkers, runsFleetJobs };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { HostedStore } from './channel';
2
+ import { FleetStoreName } from './link';
3
+ /**
4
+ * What the primary keeps for its workers: the same in-memory defaults a single server makes for itself, made here
5
+ * once — when a worker first asks — so the fleet has one of each rather than one per worker.
6
+ */
7
+ export declare const FLEET_STORES: Readonly<Record<FleetStoreName, HostedStore>>;
@@ -0,0 +1,19 @@
1
+ import { JOB_QUEUE_METHODS, createMemoryJobQueue } from "../../../modules/actions/jobs/memoryQueue.js";
2
+ import { hostable } from "./channel.js";
3
+ import { KV_METHODS, createMemoryKv } from "../../../modules/actions/runtime/memoryKv.js";
4
+ import { DRAFT_STORE_METHODS, createMemoryDraftStore } from "../../../modules/ssr/preview.js";
5
+ import { RATE_LIMIT_METHODS, createMemoryRateLimit } from "../../auth/throttle.js";
6
+ //#region src/core/server/fleet/stores.ts
7
+ /**
8
+ * What the primary keeps for its workers: the same in-memory defaults a single server makes for itself, made here
9
+ * once — when a worker first asks — so the fleet has one of each rather than one per worker.
10
+ */
11
+ var FLEET_STORES = {
12
+ "actions.kv": hostable(createMemoryKv, KV_METHODS),
13
+ "realtime.grants": hostable(createMemoryKv, KV_METHODS),
14
+ "actions.jobs": hostable(() => createMemoryJobQueue(), JOB_QUEUE_METHODS),
15
+ "ssr.drafts": hostable(createMemoryDraftStore, DRAFT_STORE_METHODS),
16
+ "auth.rateLimit": hostable(() => ({ check: createMemoryRateLimit() }), RATE_LIMIT_METHODS)
17
+ };
18
+ //#endregion
19
+ export { FLEET_STORES };
@@ -0,0 +1,26 @@
1
+ export type Fleet = {
2
+ stop: () => Promise<void>;
3
+ };
4
+ /**
5
+ * How long the replacement for a dead worker waits, given how many have died in the last minute. As many deaths as
6
+ * there are workers — each of them crashing once — are replaced at once; past that it doubles from half a second, up
7
+ * to thirty.
8
+ */
9
+ export declare const restartDelay: (deathsInWindow: number, count: number) => number;
10
+ /**
11
+ * Starts `count` workers from this primary, each running the process's own entry point — so each builds and binds
12
+ * its own server on the shared port, and the connections are spread between them.
13
+ *
14
+ * A worker that dies is replaced, crash or kill alike, and the replacement takes over whatever the dead one carried
15
+ * (the jobs). Past one death per worker a minute the replacements wait, longer each time (`restartDelay`), so a
16
+ * request that crashes whichever worker takes it cannot turn the primary into a fork loop.
17
+ *
18
+ * Until the fleet has served at all, a death is not retried: a worker that dies before any has listened would die
19
+ * the same way again — a port in use, a broken build — so the fleet stops and the process exits non-zero for
20
+ * whatever supervises it. Once it has served, a replacement that fails to start is retried like any other death:
21
+ * the workers still serving keep serving through a passing failure (a database that is briefly down).
22
+ *
23
+ * `stop` asks every worker to finish with SIGTERM (what `closeOnSignals` answers) and waits for all of them. A
24
+ * primary that dies without stopping them takes them with it: a worker exits when its channel to the primary closes.
25
+ */
26
+ export declare const startFleet: (count: number, label: string, exit?: (code: number) => void) => Fleet;