@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,116 @@
1
+ import { FunctionFailure } from "../protocol.js";
2
+ import { frameText } from "../../../helpers/wsFrame.js";
3
+ import { readResponseMessage } from "./messages.js";
4
+ import { WebSocket } from "ws";
5
+ //#region src/modules/functions/runner/remote.ts
6
+ /** What reading a bundle may take on the runner (its own ceiling is 5 s), and then some. */
7
+ var DESCRIBE_DEADLINE_MS = 1e4;
8
+ var unreachable = (detail) => new FunctionFailure("error", `The functions runner is unreachable (${detail})`);
9
+ /**
10
+ * The platform's side of the runner service: a {@link FunctionRunner} over one WebSocket per operation. Each call the
11
+ * code makes arrives on it and is answered on it, by this process — the one holding the run.
12
+ */
13
+ var createRemoteRunner = ({ url, secret, connectTimeoutMs = 5e3, graceMs = 5e3 }) => {
14
+ const operate = ({ first, load, bundleId, deadlineMs, answer, signal, onUsage }) => new Promise((resolve, reject) => {
15
+ const socket = new WebSocket(url, {
16
+ headers: { authorization: `Bearer ${secret}` },
17
+ handshakeTimeout: connectTimeoutMs
18
+ });
19
+ let settled = false;
20
+ const send = (message) => {
21
+ if (socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify(message));
22
+ };
23
+ const settle = (outcome) => {
24
+ if (settled) return;
25
+ settled = true;
26
+ clearTimeout(deadline);
27
+ signal?.removeEventListener("abort", onAbort);
28
+ outcome();
29
+ socket.close(1e3);
30
+ };
31
+ const deadline = setTimeout(() => {
32
+ settle(() => reject(new FunctionFailure("wall", `The functions runner did not answer within ${String(deadlineMs)} ms`)));
33
+ socket.terminate();
34
+ }, deadlineMs);
35
+ const onAbort = () => send({ type: "abort" });
36
+ signal?.addEventListener("abort", onAbort, { once: true });
37
+ socket.on("open", () => {
38
+ send(first);
39
+ if (signal?.aborted) onAbort();
40
+ });
41
+ socket.on("message", (data) => {
42
+ const message = readResponseMessage(frameText(data));
43
+ if (!message) {
44
+ settle(() => reject(new FunctionFailure("error", "The functions runner answered outside the protocol")));
45
+ return;
46
+ }
47
+ switch (message.type) {
48
+ case "needBundle":
49
+ load().then((code) => send({
50
+ type: "bundle",
51
+ bundle: {
52
+ id: bundleId,
53
+ code
54
+ }
55
+ }), (error) => settle(() => reject(new FunctionFailure("error", `The functions could not be read: ${error instanceof Error ? error.message : String(error)}`))));
56
+ return;
57
+ case "call":
58
+ answer(message.call).then((value) => send({
59
+ type: "answer",
60
+ id: message.id,
61
+ answer: {
62
+ ok: true,
63
+ value: value ?? null
64
+ }
65
+ }), (error) => send({
66
+ type: "answer",
67
+ id: message.id,
68
+ answer: {
69
+ ok: false,
70
+ error: error instanceof Error ? error.message : String(error)
71
+ }
72
+ }));
73
+ return;
74
+ case "done":
75
+ if (message.usage) onUsage?.(message.usage);
76
+ settle(() => resolve(message.value));
77
+ return;
78
+ case "failed":
79
+ if (message.usage) onUsage?.(message.usage);
80
+ settle(() => reject(new FunctionFailure(message.reason, message.error)));
81
+ }
82
+ });
83
+ socket.on("error", (error) => settle(() => reject(unreachable(error.message))));
84
+ socket.on("close", (code) => settle(() => reject(unreachable(`closed with ${String(code)}`))));
85
+ });
86
+ return {
87
+ describe: (bundle) => operate({
88
+ first: {
89
+ type: "describe",
90
+ protocol: 1,
91
+ bundle
92
+ },
93
+ load: () => Promise.resolve(bundle.code),
94
+ bundleId: bundle.id,
95
+ deadlineMs: DESCRIBE_DEADLINE_MS,
96
+ answer: () => Promise.reject(/* @__PURE__ */ new Error("Nothing is reachable while a bundle is read"))
97
+ }),
98
+ invoke: ({ bundle, invocation, limits, answer, signal, onUsage }) => operate({
99
+ first: {
100
+ type: "invoke",
101
+ protocol: 1,
102
+ bundleId: bundle.id,
103
+ invocation,
104
+ limits
105
+ },
106
+ load: bundle.load,
107
+ bundleId: bundle.id,
108
+ deadlineMs: limits.wallMs + graceMs,
109
+ answer,
110
+ signal,
111
+ onUsage
112
+ })
113
+ };
114
+ };
115
+ //#endregion
116
+ export { createRemoteRunner };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { default as http } from 'node:http';
2
+ import { FunctionRunner } from '../protocol';
3
+ import { IsolateRunnerOptions } from '../sandbox/isolate';
4
+ import { AddressInfo } from 'node:net';
5
+ export type FunctionsRunnerServiceOptions = IsolateRunnerOptions & {
6
+ /** What the platform presents as `Authorization: Bearer <secret>`. Required: a runner anybody reaches runs anybody's code. */
7
+ secret: string;
8
+ port?: number;
9
+ host?: string;
10
+ /**
11
+ * The engine; the isolates in this process by default, warmed before the service listens. It keeps the bundles it
12
+ * runs — this service keeps none of its own — and asks the platform for one it does not have.
13
+ */
14
+ runner?: FunctionRunner;
15
+ /**
16
+ * What answers plain HTTP besides `/health` — a space runtime's endpoints — behind the same secret as the protocol.
17
+ * Answers whether it took the request; one it did not take is a 404.
18
+ */
19
+ http?: (req: http.IncomingMessage, res: http.ServerResponse) => Promise<boolean>;
20
+ };
21
+ export type FunctionsRunnerService = {
22
+ /** Where it listens, once it does. */
23
+ address: () => AddressInfo;
24
+ close: () => Promise<void>;
25
+ };
26
+ /**
27
+ * The functions runner as a service: a process that holds no secrets, no database and no documents, and runs the
28
+ * spaces' code in isolates for the platform that authenticates to it. What a sandbox escape reaches is this process.
29
+ *
30
+ * `GET /health` answers 200 for the orchestrator; everything else is the WebSocket protocol, behind the secret.
31
+ */
32
+ export declare const startFunctionsRunnerService: ({ secret, port, host, runner, http: answerHttp, ...isolate }: FunctionsRunnerServiceOptions) => Promise<FunctionsRunnerService>;
@@ -0,0 +1,209 @@
1
+ import { serverLog } from "../../../helpers/serverLog.js";
2
+ import { FunctionFailure } from "../protocol.js";
3
+ import { frameText } from "../../../helpers/wsFrame.js";
4
+ import { watchConnections } from "../../../core/server/drain.js";
5
+ import { readRequestMessage } from "./messages.js";
6
+ import { createIsolateRunner } from "../sandbox/isolate.js";
7
+ import { createHash, timingSafeEqual } from "node:crypto";
8
+ import http from "node:http";
9
+ import { WebSocketServer } from "ws";
10
+ //#region src/modules/functions/runner/service.ts
11
+ /** A bundle is at most 1 MB and an answer a few; anything past this on one frame is not the platform talking. */
12
+ var MAX_FRAME_BYTES = 8388608;
13
+ var digest = (value) => createHash("sha256").update(value).digest();
14
+ var authorised = (header, secret) => header !== void 0 && timingSafeEqual(digest(header), digest(`Bearer ${secret}`));
15
+ /**
16
+ * One operation on one connection — `describe`, or `invoke` with every call the code makes going back on the same
17
+ * socket. The platform replica that asked is the one answering, so nothing about a run has to be shared between
18
+ * replicas, and a connection that closes is the invocation aborting.
19
+ */
20
+ var serveConnection = (socket, runner) => {
21
+ const pending = /* @__PURE__ */ new Map();
22
+ const controller = new AbortController();
23
+ let nextCall = 1;
24
+ let started = false;
25
+ let waitingBundle;
26
+ const send = (message) => {
27
+ if (socket.readyState === socket.OPEN) socket.send(JSON.stringify(message));
28
+ };
29
+ const finish = (message) => {
30
+ send(message);
31
+ socket.close(1e3);
32
+ };
33
+ let usage;
34
+ const settle = (work) => {
35
+ work.then((value) => finish({
36
+ type: "done",
37
+ value,
38
+ ...usage ? { usage } : {}
39
+ }), (error) => finish({
40
+ type: "failed",
41
+ ...error instanceof FunctionFailure ? {
42
+ reason: error.reason,
43
+ error: error.message
44
+ } : {
45
+ reason: "error",
46
+ error: error instanceof Error ? error.message : String(error)
47
+ },
48
+ ...usage ? { usage } : {}
49
+ }));
50
+ };
51
+ const answer = (call) => new Promise((resolve, reject) => {
52
+ const id = nextCall++;
53
+ pending.set(id, (reply) => reply.ok ? resolve(reply.value) : reject(new Error(reply.error)));
54
+ send({
55
+ type: "call",
56
+ id,
57
+ call
58
+ });
59
+ });
60
+ socket.on("message", (data) => {
61
+ const message = readRequestMessage(frameText(data));
62
+ if (!message) {
63
+ finish({
64
+ type: "failed",
65
+ reason: "error",
66
+ error: "Not a message of the functions protocol"
67
+ });
68
+ return;
69
+ }
70
+ if (message.type === "answer") {
71
+ const reply = pending.get(message.id);
72
+ pending.delete(message.id);
73
+ reply?.(message.answer);
74
+ return;
75
+ }
76
+ if (message.type === "abort") {
77
+ controller.abort();
78
+ return;
79
+ }
80
+ if (message.type === "bundle") {
81
+ waitingBundle?.(message.bundle.code);
82
+ waitingBundle = void 0;
83
+ return;
84
+ }
85
+ if (started) {
86
+ finish({
87
+ type: "failed",
88
+ reason: "error",
89
+ error: "One operation per connection"
90
+ });
91
+ return;
92
+ }
93
+ started = true;
94
+ if (message.protocol !== 1) {
95
+ finish({
96
+ type: "failed",
97
+ reason: "error",
98
+ error: `This runner speaks protocol ${String(1)}, not ${String(message.protocol)}`
99
+ });
100
+ return;
101
+ }
102
+ if (message.type === "describe") {
103
+ settle(runner.describe(message.bundle));
104
+ return;
105
+ }
106
+ const { bundleId, invocation, limits } = message;
107
+ settle(runner.invoke({
108
+ bundle: {
109
+ id: bundleId,
110
+ load: () => new Promise((resolve) => {
111
+ waitingBundle = resolve;
112
+ send({ type: "needBundle" });
113
+ })
114
+ },
115
+ invocation,
116
+ limits,
117
+ answer,
118
+ signal: controller.signal,
119
+ onUsage: (spent) => {
120
+ usage = spent;
121
+ }
122
+ }));
123
+ });
124
+ socket.on("close", () => {
125
+ controller.abort();
126
+ pending.forEach((reply) => reply({
127
+ ok: false,
128
+ error: "The platform went away"
129
+ }));
130
+ pending.clear();
131
+ });
132
+ };
133
+ /**
134
+ * The functions runner as a service: a process that holds no secrets, no database and no documents, and runs the
135
+ * spaces' code in isolates for the platform that authenticates to it. What a sandbox escape reaches is this process.
136
+ *
137
+ * `GET /health` answers 200 for the orchestrator; everything else is the WebSocket protocol, behind the secret.
138
+ */
139
+ var startFunctionsRunnerService = async ({ secret, port = 8790, host = "0.0.0.0", runner, http: answerHttp, ...isolate }) => {
140
+ if (secret.length < 32) throw new Error("The functions runner needs a secret of at least 32 characters");
141
+ let engine;
142
+ if (runner) engine = runner;
143
+ else {
144
+ const isolates = createIsolateRunner(isolate);
145
+ await isolates.warm();
146
+ engine = isolates;
147
+ }
148
+ const sockets = new WebSocketServer({
149
+ noServer: true,
150
+ maxPayload: MAX_FRAME_BYTES
151
+ });
152
+ const notFound = (res) => {
153
+ res.writeHead(404, { "content-type": "text/plain" });
154
+ res.end("");
155
+ };
156
+ const server = http.createServer((req, res) => {
157
+ if (req.method === "GET" && req.url === "/health") {
158
+ res.writeHead(200, { "content-type": "text/plain" });
159
+ res.end("ok");
160
+ return;
161
+ }
162
+ if (!answerHttp) {
163
+ notFound(res);
164
+ return;
165
+ }
166
+ if (!authorised(req.headers.authorization, secret)) {
167
+ res.writeHead(401, { "content-type": "text/plain" });
168
+ res.end("");
169
+ return;
170
+ }
171
+ answerHttp(req, res).then((taken) => {
172
+ if (!taken) notFound(res);
173
+ }, (error) => {
174
+ serverLog.error("Functions", "an HTTP request failed", error);
175
+ if (!res.headersSent) res.writeHead(500, { "content-type": "text/plain" });
176
+ res.end("");
177
+ });
178
+ });
179
+ server.on("upgrade", (req, socket, head) => {
180
+ if (!authorised(req.headers.authorization, secret)) {
181
+ socket.end("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
182
+ return;
183
+ }
184
+ sockets.handleUpgrade(req, socket, head, (ws) => serveConnection(ws, engine));
185
+ });
186
+ const connections = watchConnections(server);
187
+ await new Promise((resolve, reject) => {
188
+ server.once("error", reject);
189
+ server.listen(port, host, () => {
190
+ server.off("error", reject);
191
+ resolve();
192
+ });
193
+ });
194
+ serverLog.info("Functions", `runner listening on ${host}:${String(port)}`);
195
+ return {
196
+ address: () => {
197
+ const address = server.address();
198
+ if (!address || typeof address === "string") throw new Error("The functions runner is not listening");
199
+ return address;
200
+ },
201
+ close: async () => {
202
+ sockets.clients.forEach((client) => client.terminate());
203
+ await connections.drain("Functions");
204
+ await engine.close?.();
205
+ }
206
+ };
207
+ };
208
+ //#endregion
209
+ export { startFunctionsRunnerService };
@@ -0,0 +1,45 @@
1
+ import { changeKv } from '../../actions/runtime/kvChange';
2
+ import { createFunctionsDriver, describeFunctions } from '../driver';
3
+ /** What the runner hands the guest: calls into the runner's own process, the only way out of the isolate. */
4
+ export type GuestHost = {
5
+ /** A {@link FunctionCall} for the platform, as JSON; answers a `FunctionAnswer`, as JSON. */
6
+ call: (message: string) => Promise<string>;
7
+ /** Resolves after `ms` — the runner's clock, bounded by the invocation's time. */
8
+ sleep: (ms: number) => Promise<void>;
9
+ /** `length` random bytes, from the runner's CSPRNG. */
10
+ random: (length: number) => number[];
11
+ /** A `crypto.subtle` operation the runner does with its own implementation: `{ op, … }` → a `FunctionAnswer` whose
12
+ * value is the bytes, base64. */
13
+ crypto: (message: string) => Promise<string>;
14
+ };
15
+ /**
16
+ * Functions of the platform's the guest runs as they are, printed in beside it (`isolate.ts`) — one implementation for
17
+ * native code and the sandbox alike. Each is self-contained by contract, as the guest is.
18
+ */
19
+ export type GuestShared = {
20
+ /** `ctx.kv.change`: the read-change-write loop, over the guest's own `get` and `swap` calls. */
21
+ changeKv: typeof changeKv;
22
+ /** What a definition declares, as a manifest. */
23
+ describeFunctions: typeof describeFunctions;
24
+ /** An invocation of a definition with its `ctx` — the same driver a space runtime runs. */
25
+ createFunctionsDriver: typeof createFunctionsDriver;
26
+ };
27
+ /** What the runner drives the guest with, once installed. */
28
+ export type GuestDriver = {
29
+ /** What a definition declares — the manifest the platform reads and checks — as a `FunctionAnswer` (JSON). */
30
+ describe: (definition: unknown) => string;
31
+ /** Runs one invocation (JSON) of a definition, and answers a `FunctionAnswer` (JSON). Never rejects. */
32
+ invoke: (definition: unknown, invocation: string) => Promise<string>;
33
+ /** The run was aborted: `ctx.signal` fires, for code that listens, before the runner stops it. */
34
+ abort: (reason: string) => void;
35
+ };
36
+ /**
37
+ * The runtime a space's code finds in an isolate: the web APIs a bare V8 lacks (`Headers`, `Request`, `Response`,
38
+ * `TextEncoder`, `AbortSignal`, timers, `crypto`) and the `ctx` its functions are handed.
39
+ *
40
+ * It is installed by PRINTING this function into the isolate (`installGuest.toString()`), after the prelude that brings
41
+ * `URL`, `atob`, `structuredClone` and `DOMException`. So it may use nothing from outside its own body — no import,
42
+ * no helper beside it — and all it has of the runner is `host`, and the functions in `shared`. Streams are not
43
+ * provided: a body is text or bytes.
44
+ */
45
+ export declare const installGuest: (scope: Record<string, unknown>, host: GuestHost, shared: GuestShared) => GuestDriver;