@plitzi/sdk-server 0.37.1 → 0.37.3

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 (386) hide show
  1. package/CHANGELOG.md +1296 -0
  2. package/README.md +126 -7
  3. package/dist/actions.d.ts +20 -8
  4. package/dist/actions.js +11 -4
  5. package/dist/adapters/cloudAdapters.js +4 -3
  6. package/dist/adapters/jsonAdapters.js +28 -6
  7. package/dist/auth.d.ts +7 -4
  8. package/dist/auth.js +8 -6
  9. package/dist/core/auth/api.d.ts +29 -1
  10. package/dist/core/auth/api.js +47 -13
  11. package/dist/core/auth/createAuth.d.ts +4 -0
  12. package/dist/core/auth/createAuth.js +3 -3
  13. package/dist/core/auth/credentials.d.ts +3 -0
  14. package/dist/core/auth/credentials.js +1 -1
  15. package/dist/core/auth/csrf.d.ts +25 -1
  16. package/dist/core/auth/csrf.js +29 -4
  17. package/dist/core/auth/renewal.d.ts +26 -0
  18. package/dist/core/auth/renewal.js +24 -0
  19. package/dist/core/auth/routes.js +8 -6
  20. package/dist/core/auth/session.d.ts +45 -0
  21. package/dist/core/auth/session.js +47 -1
  22. package/dist/core/auth/sessionActivity.d.ts +11 -0
  23. package/dist/core/auth/sessionActivity.js +14 -0
  24. package/dist/core/auth/throttle.d.ts +15 -0
  25. package/dist/core/auth/throttle.js +29 -1
  26. package/dist/core/auth/totp.d.ts +9 -1
  27. package/dist/core/auth/totp.js +11 -6
  28. package/dist/core/createServer.actions.test.d.ts +1 -0
  29. package/dist/core/createServer.d.ts +14 -1
  30. package/dist/core/createServer.functions.test.d.ts +1 -0
  31. package/dist/core/createServer.js +22 -12
  32. package/dist/core/fontStore.js +1 -1
  33. package/dist/core/handlers/authRouteHandlers.d.ts +1 -1
  34. package/dist/core/handlers/authRouteHandlers.js +57 -21
  35. package/dist/core/handlers/csrfMiddleware.d.ts +23 -0
  36. package/dist/core/handlers/csrfMiddleware.js +31 -7
  37. package/dist/core/handlers/csrfMiddleware.test.d.ts +1 -0
  38. package/dist/core/handlers/oauthRouteHandlers.js +5 -3
  39. package/dist/core/handlers/socialRouteHandlers.d.ts +1 -1
  40. package/dist/core/handlers/socialRouteHandlers.js +2 -1
  41. package/dist/core/http/dispatcher.d.ts +9 -1
  42. package/dist/core/http/dispatcher.js +38 -11
  43. package/dist/core/http/navigation.d.ts +5 -2
  44. package/dist/core/http/navigation.js +7 -4
  45. package/dist/core/http/socketResponse.d.ts +18 -0
  46. package/dist/core/http/socketResponse.js +59 -0
  47. package/dist/core/http/sse.d.ts +26 -0
  48. package/dist/core/http/sse.js +78 -0
  49. package/dist/core/http/stages/authRoutes.js +3 -1
  50. package/dist/core/http/stages/exchangeRoute.test.d.ts +1 -0
  51. package/dist/core/http/stages/middlewares.d.ts +1 -1
  52. package/dist/core/http/stages/middlewares.js +16 -10
  53. package/dist/core/http/stages/middlewares.test.d.ts +1 -0
  54. package/dist/core/http/stages/oauth.js +2 -2
  55. package/dist/core/http/stages/sessionRenewal.d.ts +16 -0
  56. package/dist/core/http/stages/sessionRenewal.js +81 -0
  57. package/dist/core/http/stages/sessionRenewal.test.d.ts +1 -0
  58. package/dist/core/http/stages/signInRoute.d.ts +2 -0
  59. package/dist/core/http/stages/signInRoute.js +139 -0
  60. package/dist/core/http/stages/signInRoute.test.d.ts +1 -0
  61. package/dist/core/http/types.d.ts +9 -0
  62. package/dist/core/http/webExchange.d.ts +18 -0
  63. package/dist/core/http/webExchange.js +53 -0
  64. package/dist/core/oauth/authorize.js +37 -13
  65. package/dist/core/oauth/consentPage.js +11 -0
  66. package/dist/core/oauth/issueContext.d.ts +14 -0
  67. package/dist/core/oauth/issueContext.js +32 -0
  68. package/dist/core/oauth/records.d.ts +7 -0
  69. package/dist/core/oauth/register.d.ts +2 -0
  70. package/dist/core/oauth/register.js +32 -11
  71. package/dist/core/oauth/register.test.d.ts +1 -0
  72. package/dist/core/oauth/token.js +21 -6
  73. package/dist/core/oauth/token.test.d.ts +1 -0
  74. package/dist/core/requestParser.d.ts +4 -0
  75. package/dist/core/requestParser.js +14 -7
  76. package/dist/core/sdkAssets.js +1 -1
  77. package/dist/core/server/baseServer.d.ts +14 -1
  78. package/dist/core/server/baseServer.js +43 -11
  79. package/dist/core/server/closeOnSignals.d.ts +28 -0
  80. package/dist/core/server/closeOnSignals.js +47 -0
  81. package/dist/core/server/closeOnSignals.test.d.ts +1 -0
  82. package/dist/core/server/drain.d.ts +18 -0
  83. package/dist/core/server/drain.js +62 -0
  84. package/dist/core/server/drain.test.d.ts +1 -0
  85. package/dist/core/server/fleet/channel.d.ts +103 -0
  86. package/dist/core/server/fleet/channel.js +191 -0
  87. package/dist/core/server/fleet/channel.test.d.ts +1 -0
  88. package/dist/core/server/fleet/fixtures/fleetServer.d.ts +1 -0
  89. package/dist/core/server/fleet/fleet.integration.test.d.ts +1 -0
  90. package/dist/core/server/fleet/link.d.ts +23 -0
  91. package/dist/core/server/fleet/link.js +70 -0
  92. package/dist/core/server/fleet/relay.d.ts +11 -0
  93. package/dist/core/server/fleet/relay.js +104 -0
  94. package/dist/core/server/fleet/relay.test.d.ts +1 -0
  95. package/dist/core/server/fleet/role.d.ts +46 -0
  96. package/dist/core/server/fleet/role.js +59 -0
  97. package/dist/core/server/fleet/role.test.d.ts +1 -0
  98. package/dist/core/server/fleet/stores.d.ts +7 -0
  99. package/dist/core/server/fleet/stores.js +19 -0
  100. package/dist/core/server/fleet/supervisor.d.ts +26 -0
  101. package/dist/core/server/fleet/supervisor.js +108 -0
  102. package/dist/core/server/fleet/supervisor.test.d.ts +1 -0
  103. package/dist/core/server/pageServer.js +36 -5
  104. package/dist/core/services/action.js +10 -2
  105. package/dist/core/services/functionRoutes.d.ts +9 -0
  106. package/dist/core/services/functionRoutes.js +47 -0
  107. package/dist/core/services/realtime.d.ts +8 -0
  108. package/dist/core/services/realtime.js +57 -0
  109. package/dist/core/services/registry.js +6 -2
  110. package/dist/core/staticFiles.js +12 -4
  111. package/dist/core/staticFiles.test.d.ts +1 -0
  112. package/dist/core/transports.d.ts +13 -3
  113. package/dist/core/transports.js +14 -5
  114. package/dist/functions-api.d.ts +281 -0
  115. package/dist/functions.d.ts +19 -0
  116. package/dist/functions.js +5 -0
  117. package/dist/functionsRunner.d.ts +15 -0
  118. package/dist/functionsRunner.js +6 -0
  119. package/dist/handlers.d.ts +2 -2
  120. package/dist/handlers.js +2 -2
  121. package/dist/helpers/atomicFile.d.ts +10 -0
  122. package/dist/helpers/atomicFile.js +33 -0
  123. package/dist/helpers/atomicFile.test.d.ts +1 -0
  124. package/dist/helpers/buildResponseHelpers.js +35 -11
  125. package/dist/helpers/buildServerInfo.js +4 -2
  126. package/dist/helpers/buildServerInfo.test.d.ts +1 -0
  127. package/dist/helpers/cache/CompressedFileCache.d.ts +18 -0
  128. package/dist/helpers/cache/CompressedFileCache.js +44 -0
  129. package/dist/helpers/cache/CompressedFileCache.test.d.ts +1 -0
  130. package/dist/helpers/cache/cacheManager.d.ts +1 -1
  131. package/dist/helpers/cache/cacheManager.js +2 -1
  132. package/dist/helpers/cache/cacheManager.test.d.ts +1 -0
  133. package/dist/helpers/cache/index.d.ts +1 -1
  134. package/dist/helpers/cache/keys.d.ts +15 -1
  135. package/dist/helpers/cache/keys.js +47 -5
  136. package/dist/helpers/cache/serverCaches.d.ts +7 -1
  137. package/dist/helpers/compress.d.ts +3 -1
  138. package/dist/helpers/compress.js +11 -3
  139. package/dist/helpers/hydrationPayload.d.ts +11 -0
  140. package/dist/helpers/hydrationPayload.js +51 -0
  141. package/dist/helpers/hydrationPayload.test.d.ts +1 -0
  142. package/dist/helpers/metrics.d.ts +1 -1
  143. package/dist/helpers/metrics.js +3 -2
  144. package/dist/helpers/outboundGuard.d.ts +14 -6
  145. package/dist/helpers/outboundGuard.js +132 -8
  146. package/dist/helpers/paintedCookie.d.ts +8 -0
  147. package/dist/helpers/paintedCookie.js +13 -0
  148. package/dist/helpers/reportReactBuild.d.ts +9 -0
  149. package/dist/helpers/reportReactBuild.js +18 -0
  150. package/dist/helpers/reportReactBuild.test.d.ts +1 -0
  151. package/dist/helpers/serverLog.d.ts +25 -1
  152. package/dist/helpers/serverLog.js +68 -3
  153. package/dist/helpers/serverLog.test.d.ts +1 -0
  154. package/dist/helpers/wsFrame.d.ts +3 -0
  155. package/dist/helpers/wsFrame.js +5 -0
  156. package/dist/index.d.ts +8 -1
  157. package/dist/index.js +6 -2
  158. package/dist/kernel.d.ts +2 -1
  159. package/dist/kernel.js +3 -2
  160. package/dist/modules/actions/connectorWrite.js +2 -1
  161. package/dist/modules/actions/index.d.ts +41 -13
  162. package/dist/modules/actions/index.js +52 -9
  163. package/dist/modules/actions/jobs/failureStreak.d.ts +17 -0
  164. package/dist/modules/actions/jobs/failureStreak.js +47 -0
  165. package/dist/modules/actions/jobs/failureStreak.test.d.ts +1 -0
  166. package/dist/modules/actions/jobs/index.d.ts +33 -0
  167. package/dist/modules/actions/jobs/index.js +59 -0
  168. package/dist/modules/actions/jobs/memoryQueue.d.ts +33 -0
  169. package/dist/modules/actions/jobs/memoryQueue.js +194 -0
  170. package/dist/modules/actions/jobs/memoryStores.test.d.ts +1 -0
  171. package/dist/modules/actions/jobs/scheduler.d.ts +64 -0
  172. package/dist/modules/actions/jobs/scheduler.js +130 -0
  173. package/dist/modules/actions/jobs/scheduler.test.d.ts +1 -0
  174. package/dist/modules/actions/jobs/schedules.d.ts +23 -0
  175. package/dist/modules/actions/jobs/schedules.js +47 -0
  176. package/dist/modules/actions/jobs/storeClock.d.ts +16 -0
  177. package/dist/modules/actions/jobs/storeClock.js +32 -0
  178. package/dist/modules/actions/jobs/testing/jobQueueContract.d.ts +25 -0
  179. package/dist/modules/actions/jobs/worker.d.ts +64 -0
  180. package/dist/modules/actions/jobs/worker.js +267 -0
  181. package/dist/modules/actions/jobs/worker.test.d.ts +1 -0
  182. package/dist/modules/actions/moduleFor.js +6 -2
  183. package/dist/modules/actions/runtime/errors.d.ts +12 -0
  184. package/dist/modules/actions/runtime/errors.js +16 -1
  185. package/dist/modules/actions/runtime/kvChange.d.ts +27 -0
  186. package/dist/modules/actions/runtime/kvChange.js +23 -0
  187. package/dist/modules/actions/runtime/kvList.d.ts +51 -0
  188. package/dist/modules/actions/runtime/kvList.js +52 -0
  189. package/dist/modules/actions/runtime/kvStore.d.ts +8 -0
  190. package/dist/modules/actions/runtime/kvStore.js +46 -20
  191. package/dist/modules/actions/runtime/memoryKv.d.ts +3 -0
  192. package/dist/modules/actions/runtime/memoryKv.js +19 -1
  193. package/dist/modules/actions/runtime/namespaceKv.d.ts +4 -6
  194. package/dist/modules/actions/runtime/namespaceKv.js +15 -3
  195. package/dist/modules/actions/runtime/namespaceKv.test.d.ts +1 -0
  196. package/dist/modules/actions/runtime/precheck.js +5 -9
  197. package/dist/modules/actions/runtime/rateLimit.d.ts +19 -0
  198. package/dist/modules/actions/runtime/rateLimit.js +19 -0
  199. package/dist/modules/actions/runtime/redisKv.d.ts +27 -0
  200. package/dist/modules/actions/runtime/redisKv.integration.test.d.ts +1 -0
  201. package/dist/modules/actions/runtime/redisKv.js +46 -0
  202. package/dist/modules/actions/runtime/renderResolver.js +2 -2
  203. package/dist/modules/actions/runtime/report.js +2 -1
  204. package/dist/modules/actions/runtime/runAction.d.ts +10 -2
  205. package/dist/modules/actions/runtime/runAction.js +52 -116
  206. package/dist/modules/actions/runtime/runLogger.d.ts +5 -0
  207. package/dist/modules/actions/runtime/runLogger.js +8 -2
  208. package/dist/modules/actions/runtime/signing.d.ts +20 -0
  209. package/dist/modules/actions/runtime/signing.js +25 -0
  210. package/dist/modules/actions/runtime/signing.test.d.ts +1 -0
  211. package/dist/modules/actions/runtime/taskContext.d.ts +33 -0
  212. package/dist/modules/actions/runtime/taskContext.js +124 -0
  213. package/dist/modules/actions/tasks/builtins.js +5 -1
  214. package/dist/modules/actions/tasks/flow.js +81 -10
  215. package/dist/modules/actions/tasks/helpers.js +2 -2
  216. package/dist/modules/actions/tasks/http.js +2 -3
  217. package/dist/modules/actions/tasks/kv.js +39 -0
  218. package/dist/modules/actions/tasks/list.d.ts +2 -0
  219. package/dist/modules/actions/tasks/list.js +145 -0
  220. package/dist/modules/actions/tasks/realtime.d.ts +2 -0
  221. package/dist/modules/actions/tasks/realtime.js +104 -0
  222. package/dist/modules/actions/tasks/registry.d.ts +10 -1
  223. package/dist/modules/actions/tasks/registry.js +17 -6
  224. package/dist/modules/actions/transport/callHandler.js +6 -3
  225. package/dist/modules/actions/transport/catalogHandler.d.ts +5 -2
  226. package/dist/modules/actions/transport/catalogHandler.js +3 -2
  227. package/dist/modules/actions/transport/stream.d.ts +4 -5
  228. package/dist/modules/actions/transport/stream.js +12 -76
  229. package/dist/modules/actions/transport/webhookHandler.js +5 -4
  230. package/dist/modules/actions/types.d.ts +162 -4
  231. package/dist/modules/connectors/engine.js +3 -5
  232. package/dist/modules/functions/build.d.ts +22 -0
  233. package/dist/modules/functions/build.js +122 -0
  234. package/dist/modules/functions/build.test.d.ts +1 -0
  235. package/dist/modules/functions/capabilities.d.ts +22 -0
  236. package/dist/modules/functions/capabilities.js +228 -0
  237. package/dist/modules/functions/config.d.ts +34 -0
  238. package/dist/modules/functions/config.js +24 -0
  239. package/dist/modules/functions/context.d.ts +17 -0
  240. package/dist/modules/functions/context.js +88 -0
  241. package/dist/modules/functions/contract.d.ts +121 -0
  242. package/dist/modules/functions/contract.js +9 -0
  243. package/dist/modules/functions/driver.d.ts +36 -0
  244. package/dist/modules/functions/driver.js +150 -0
  245. package/dist/modules/functions/load.d.ts +15 -0
  246. package/dist/modules/functions/load.js +45 -0
  247. package/dist/modules/functions/load.test.d.ts +1 -0
  248. package/dist/modules/functions/local.d.ts +29 -0
  249. package/dist/modules/functions/local.js +61 -0
  250. package/dist/modules/functions/local.test.d.ts +1 -0
  251. package/dist/modules/functions/manifest.d.ts +24 -0
  252. package/dist/modules/functions/manifest.js +163 -0
  253. package/dist/modules/functions/manifest.test.d.ts +1 -0
  254. package/dist/modules/functions/native.d.ts +8 -0
  255. package/dist/modules/functions/native.js +21 -0
  256. package/dist/modules/functions/native.test.d.ts +1 -0
  257. package/dist/modules/functions/protocol.d.ts +216 -0
  258. package/dist/modules/functions/protocol.js +18 -0
  259. package/dist/modules/functions/routes.d.ts +36 -0
  260. package/dist/modules/functions/routes.js +181 -0
  261. package/dist/modules/functions/routes.test.d.ts +1 -0
  262. package/dist/modules/functions/runner/messages.d.ts +5 -0
  263. package/dist/modules/functions/runner/messages.js +188 -0
  264. package/dist/modules/functions/runner/remote.d.ts +19 -0
  265. package/dist/modules/functions/runner/remote.js +116 -0
  266. package/dist/modules/functions/runner/remote.test.d.ts +1 -0
  267. package/dist/modules/functions/runner/service.d.ts +32 -0
  268. package/dist/modules/functions/runner/service.js +209 -0
  269. package/dist/modules/functions/sandbox/guest.d.ts +45 -0
  270. package/dist/modules/functions/sandbox/guest.js +660 -0
  271. package/dist/modules/functions/sandbox/isolate.d.ts +37 -0
  272. package/dist/modules/functions/sandbox/isolate.js +347 -0
  273. package/dist/modules/functions/sandbox/isolate.test.d.ts +1 -0
  274. package/dist/modules/functions/sandbox/prelude.d.ts +2 -0
  275. package/dist/modules/functions/sandbox/prelude.js +49 -0
  276. package/dist/modules/functions/space.d.ts +40 -0
  277. package/dist/modules/functions/space.js +162 -0
  278. package/dist/modules/functions/testing/tasksOf.d.ts +4 -0
  279. package/dist/modules/functions/tryEntry.d.ts +9 -0
  280. package/dist/modules/functions/tryEntry.js +49 -0
  281. package/dist/modules/mongo/index.d.ts +4 -0
  282. package/dist/modules/mongo/jobQueue.d.ts +38 -0
  283. package/dist/modules/mongo/jobQueue.js +335 -0
  284. package/dist/modules/mongo/kv.d.ts +15 -0
  285. package/dist/modules/mongo/kv.js +129 -0
  286. package/dist/modules/mongo/stores.integration.test.d.ts +1 -0
  287. package/dist/modules/mysql/accounts.js +19 -9
  288. package/dist/modules/mysql/index.d.ts +2 -1
  289. package/dist/modules/mysql/jobs/index.d.ts +5 -0
  290. package/dist/modules/mysql/jobs/jobQueue.d.ts +40 -0
  291. package/dist/modules/mysql/jobs/jobQueue.js +375 -0
  292. package/dist/modules/mysql/jobs/kv.d.ts +18 -0
  293. package/dist/modules/mysql/jobs/kv.js +108 -0
  294. package/dist/modules/mysql/jobs/schema.d.ts +33 -0
  295. package/dist/modules/mysql/jobs/schema.js +113 -0
  296. package/dist/modules/mysql/jobs/stores.integration.test.d.ts +1 -0
  297. package/dist/modules/mysql/schema.js +25 -0
  298. package/dist/modules/mysql/sessions.d.ts +1 -11
  299. package/dist/modules/mysql/sessions.js +6 -1
  300. package/dist/modules/realtime/declarations.d.ts +11 -0
  301. package/dist/modules/realtime/declarations.js +26 -0
  302. package/dist/modules/realtime/grants.d.ts +23 -0
  303. package/dist/modules/realtime/grants.js +61 -0
  304. package/dist/modules/realtime/handlers.d.ts +74 -0
  305. package/dist/modules/realtime/handlers.js +224 -0
  306. package/dist/modules/realtime/hub.d.ts +62 -0
  307. package/dist/modules/realtime/hub.js +141 -0
  308. package/dist/modules/realtime/index.d.ts +51 -0
  309. package/dist/modules/realtime/index.js +62 -0
  310. package/dist/modules/realtime/memoryPubSub.d.ts +10 -0
  311. package/dist/modules/realtime/memoryPubSub.js +43 -0
  312. package/dist/modules/realtime/realtime.test.d.ts +1 -0
  313. package/dist/modules/realtime/redisPubSub.d.ts +24 -0
  314. package/dist/modules/realtime/redisPubSub.js +36 -0
  315. package/dist/modules/realtime/redisPubSub.test.d.ts +1 -0
  316. package/dist/modules/realtime/socket.d.ts +25 -0
  317. package/dist/modules/realtime/socket.js +122 -0
  318. package/dist/modules/realtime/socket.test.d.ts +1 -0
  319. package/dist/modules/rsc/handler.d.ts +16 -0
  320. package/dist/modules/rsc/handler.js +17 -10
  321. package/dist/modules/rsc/handler.test.d.ts +1 -0
  322. package/dist/modules/rsc/resolveRscData.js +2 -1
  323. package/dist/modules/runtime/bundle.d.ts +24 -0
  324. package/dist/modules/runtime/bundle.js +102 -0
  325. package/dist/modules/runtime/contract.d.ts +37 -0
  326. package/dist/modules/runtime/contract.js +21 -0
  327. package/dist/modules/runtime/entry.test.d.ts +1 -0
  328. package/dist/modules/runtime/host.d.ts +38 -0
  329. package/dist/modules/runtime/host.js +68 -0
  330. package/dist/modules/runtime/inside.d.ts +15 -0
  331. package/dist/modules/runtime/inside.js +47 -0
  332. package/dist/modules/runtime/inside.test.d.ts +1 -0
  333. package/dist/modules/runtime/runner.d.ts +11 -0
  334. package/dist/modules/runtime/runner.js +38 -0
  335. package/dist/modules/runtime/runtime.test.d.ts +1 -0
  336. package/dist/modules/runtime/stages.d.ts +50 -0
  337. package/dist/modules/runtime/stages.js +117 -0
  338. package/dist/modules/ssr/Component.d.ts +4 -5
  339. package/dist/modules/ssr/Component.js +2 -2
  340. package/dist/modules/ssr/handler.js +10 -2
  341. package/dist/modules/ssr/loadPluginComponents.js +2 -1
  342. package/dist/modules/ssr/prepareRender.js +39 -13
  343. package/dist/modules/ssr/preview.d.ts +3 -0
  344. package/dist/modules/ssr/preview.js +17 -7
  345. package/dist/modules/ssr/redirect.test.d.ts +1 -0
  346. package/dist/modules/ssr/registerExternalPlugins.d.ts +6 -1
  347. package/dist/modules/ssr/registerExternalPlugins.js +19 -16
  348. package/dist/modules/ssr/registerExternalPlugins.test.d.ts +1 -0
  349. package/dist/modules/ssr/reportMissingPlugins.d.ts +9 -0
  350. package/dist/modules/ssr/reportMissingPlugins.js +24 -0
  351. package/dist/modules/ssr/reportMissingPlugins.test.d.ts +1 -0
  352. package/dist/modules/ssr/streamBody.d.ts +2 -2
  353. package/dist/modules/ssr/streamBody.js +4 -1
  354. package/dist/modules/ssr/template.js +1 -1
  355. package/dist/modules/ssr/views/template.ejs +8 -5
  356. package/dist/mongo.d.ts +25 -0
  357. package/dist/mongo.js +3 -0
  358. package/dist/mysql.d.ts +11 -0
  359. package/dist/mysql.js +4 -1
  360. package/dist/oauth.js +2 -2
  361. package/dist/plugins/compile.js +9 -4
  362. package/dist/plugins/copy.js +3 -3
  363. package/dist/plugins/manager.d.ts +35 -3
  364. package/dist/plugins/manager.js +109 -38
  365. package/dist/runtime.d.ts +15 -0
  366. package/dist/runtime.js +7 -0
  367. package/package.json +52 -11
  368. package/skills/plitzi-authoring/SKILL.md +153 -263
  369. package/skills/plitzi-authoring/reference/accessibility.md +111 -0
  370. package/skills/plitzi-authoring/reference/authoring-errors.md +70 -0
  371. package/skills/plitzi-authoring/reference/data-and-visibility.md +180 -0
  372. package/skills/plitzi-authoring/reference/elements-and-styles.md +161 -0
  373. package/skills/plitzi-authoring/reference/flows.md +171 -0
  374. package/skills/plitzi-authoring/reference/layouts.md +140 -0
  375. package/skills/plitzi-authoring/reference/lists.md +74 -0
  376. package/skills/plitzi-authoring/reference/performance.md +67 -0
  377. package/skills/plitzi-authoring/reference/plugins.md +167 -0
  378. package/skills/plitzi-authoring/reference/review-checklist.md +67 -0
  379. package/skills/plitzi-authoring/reference/structure.md +83 -0
  380. package/skills/plitzi-authoring/reference/templates-and-export.md +54 -0
  381. package/skills/plitzi-authoring/reference/templates.md +109 -0
  382. package/skills/plitzi-authoring/reference/testing.md +119 -0
  383. package/skills/plitzi-authoring/reference/validation.md +73 -0
  384. package/dist/modules/actions/runtime/schedule.d.ts +0 -35
  385. package/dist/modules/actions/runtime/schedule.js +0 -76
  386. /package/dist/{modules/actions/runtime/schedule.test.d.ts → adapters/jsonAdapters.test.d.ts} +0 -0
@@ -1,9 +1,20 @@
1
1
  import { builtinTasks } from "./builtins.js";
2
2
  import { dbTasks } from "./db.js";
3
+ import { nativeTasks } from "../../functions/native.js";
3
4
  //#region src/modules/actions/tasks/registry.ts
4
5
  var NAME_PATTERN = /^[a-z][a-zA-Z0-9]*$/;
5
6
  var taskName = (task) => `${task.namespace}.${task.action}`;
6
- var reservedNamespaces = new Set([...builtinTasks, ...dbTasks].map((task) => task.namespace));
7
+ /** The namespaces the platform's own tasks use: nobody else's task may take one. */
8
+ var RESERVED_NAMESPACES = new Set([...builtinTasks, ...dbTasks].map((task) => task.namespace));
9
+ /**
10
+ * What is wrong with a task's name, or nothing — one rule for a deployment's tasks at boot and a space's own when its
11
+ * functions are built. A malformed name is unreachable from any document; one in a namespace taken by another task
12
+ * set silently changes what every action using that set does.
13
+ */
14
+ var taskNameProblem = (task, reserved = RESERVED_NAMESPACES) => {
15
+ if (!NAME_PATTERN.test(task.namespace) || !NAME_PATTERN.test(task.action)) return `Invalid task name "${taskName(task)}": expected camelCase namespace and action`;
16
+ if (reserved.has(task.namespace)) return `Namespace "${task.namespace}" is reserved by another task set`;
17
+ };
7
18
  /**
8
19
  * Builds the set of tasks this server can run.
9
20
  *
@@ -11,15 +22,15 @@ var reservedNamespaces = new Set([...builtinTasks, ...dbTasks].map((task) => tas
11
22
  * name is unreachable from any document, and one shadowing a built-in silently changes what every existing action
12
23
  * in that deployment does. Both are invisible until a run misbehaves in production.
13
24
  */
14
- var createTaskRegistry = (custom = [], { db = false } = {}) => {
25
+ var createTaskRegistry = (functions = [], { db = false } = {}) => {
15
26
  const tasks = /* @__PURE__ */ new Map();
16
27
  (db ? [...builtinTasks, ...dbTasks] : builtinTasks).forEach((task) => tasks.set(taskName(task), {
17
28
  ...task,
18
29
  name: taskName(task)
19
30
  }));
20
- custom.forEach((task) => {
21
- if (!NAME_PATTERN.test(task.namespace) || !NAME_PATTERN.test(task.action)) throw new Error(`[Actions] Invalid task name "${taskName(task)}": expected camelCase namespace and action`);
22
- if (reservedNamespaces.has(task.namespace)) throw new Error(`[Actions] Namespace "${task.namespace}" is reserved by a built-in task set`);
31
+ nativeTasks(functions).forEach((task) => {
32
+ const problem = taskNameProblem(task);
33
+ if (problem) throw new Error(`[Actions] ${problem}`);
23
34
  const name = taskName(task);
24
35
  if (tasks.has(name)) throw new Error(`[Actions] Task "${name}" is registered twice`);
25
36
  tasks.set(name, {
@@ -33,4 +44,4 @@ var createTaskRegistry = (custom = [], { db = false } = {}) => {
33
44
  };
34
45
  };
35
46
  //#endregion
36
- export { createTaskRegistry, taskName };
47
+ export { RESERVED_NAMESPACES, createTaskRegistry, taskName, taskNameProblem };
@@ -1,5 +1,6 @@
1
- import { ActionRunError } from "../runtime/errors.js";
1
+ import { serverLog } from "../../../helpers/serverLog.js";
2
2
  import { triggerParams } from "../runtime/triggers.js";
3
+ import { ActionRunError } from "../runtime/errors.js";
3
4
  import { precheckRun } from "../runtime/precheck.js";
4
5
  import onAbort from "../../../helpers/onAbort.js";
5
6
  import { openStream, wantsStream } from "./stream.js";
@@ -215,6 +216,7 @@ var handleActionCall = async (deps) => {
215
216
  runId: result.runId,
216
217
  status: result.status,
217
218
  output: result.output,
219
+ ...result.error === void 0 ? {} : { error: result.error },
218
220
  ...outline ? { steps: result.steps } : {}
219
221
  }
220
222
  });
@@ -224,7 +226,8 @@ var handleActionCall = async (deps) => {
224
226
  const payload = {
225
227
  runId: result.runId,
226
228
  status: result.status,
227
- output: result.output
229
+ output: result.output,
230
+ ...result.error === void 0 ? {} : { error: result.error }
228
231
  };
229
232
  if (outline) payload.steps = result.steps;
230
233
  if (fullTrace) payload.trace = result.trace;
@@ -232,7 +235,7 @@ var handleActionCall = async (deps) => {
232
235
  } catch (error) {
233
236
  const reason = error instanceof ActionRunError ? error.reason : "failed";
234
237
  const message = error instanceof ActionRunError ? error.message : "Action failed";
235
- if (!(error instanceof ActionRunError)) console.error("[Actions] run failed:", error);
238
+ if (!(error instanceof ActionRunError)) serverLog.error("Actions", "run failed", error);
236
239
  const steps = error instanceof ActionRunError && error.steps && await showsOutline() ? error.steps : void 0;
237
240
  if (stream) {
238
241
  stream.send({
@@ -1,8 +1,11 @@
1
1
  import { ActionsModule } from '../index';
2
- import { SSRResponseHelpers } from '@plitzi/sdk-shared';
2
+ import { SpaceRevision, SSRResponseHelpers } from '@plitzi/sdk-shared';
3
3
  export type ActionCatalogDeps = {
4
4
  res: SSRResponseHelpers;
5
5
  module: ActionsModule;
6
+ /** The space asking, as of the revision it is serving: its own functions are part of what it can run. */
7
+ spaceId?: number;
8
+ at?: SpaceRevision;
6
9
  };
7
10
  /**
8
11
  * Serves the tasks this server can run.
@@ -15,4 +18,4 @@ export type ActionCatalogDeps = {
15
18
  * Session-gated by the pipeline: the catalog names a deployment's server-side capabilities, which is not something
16
19
  * to hand an anonymous visitor.
17
20
  */
18
- export declare const handleActionCatalog: ({ res, module }: ActionCatalogDeps) => void;
21
+ export declare const handleActionCatalog: ({ res, module, spaceId, at }: ActionCatalogDeps) => Promise<void>;
@@ -11,11 +11,12 @@ import { describeCatalog } from "../taskCatalog.js";
11
11
  * Session-gated by the pipeline: the catalog names a deployment's server-side capabilities, which is not something
12
12
  * to hand an anonymous visitor.
13
13
  */
14
- var handleActionCatalog = ({ res, module }) => {
14
+ var handleActionCatalog = async ({ res, module, spaceId, at }) => {
15
+ const registry = spaceId === void 0 ? module.registry : await module.registryFor(spaceId, at);
15
16
  res.setStatus(200);
16
17
  res.setHeader("Content-Type", "application/json; charset=utf-8");
17
18
  res.setHeader("Cache-Control", "no-store");
18
- res.send(JSON.stringify({ tasks: describeCatalog(module.registry) }));
19
+ res.send(JSON.stringify({ tasks: describeCatalog(registry) }));
19
20
  };
20
21
  //#endregion
21
22
  export { handleActionCatalog };
@@ -10,12 +10,11 @@ export type ActionStream = {
10
10
  isOpen: () => boolean;
11
11
  };
12
12
  /**
13
- * Opens a Server-Sent Events response.
13
+ * Opens a run's Server-Sent Events response.
14
14
  *
15
- * Written straight to the RAW response, never through the response helpers: those compress the body, set a
16
- * Content-Length and end it in one go, which is precisely what a stream cannot do. `no-transform` says the same
17
- * thing to every proxy in between, and `X-Accel-Buffering: no` says it to nginx, which otherwise holds frames
18
- * until its buffer fills and turns a live stream into one late burst.
15
+ * The run's id travels on the response head rather than in a frame: a streaming step returns as soon as the stream
16
+ * OPENS — that is what makes it a stream — so anything it learns from a frame arrives after the flow has already
17
+ * carried on. The head is the one place a caller can read the id in time to cancel the run it just started.
19
18
  */
20
19
  export declare const openStream: (raw: RawResponse, onAbort: () => void, runId: string) => ActionStream;
21
20
  /** Whether this caller asked for a stream. The negotiation is the client's, so a page that cannot read one never
@@ -1,7 +1,5 @@
1
+ import { openEventStream } from "../../../core/http/sse.js";
1
2
  //#region src/modules/actions/transport/stream.ts
2
- /** How often a comment frame goes out. Short enough that a dead peer is noticed in seconds, long enough that an
3
- * idle stream costs nothing worth counting. */
4
- var HEARTBEAT_MS = 15e3;
5
3
  /**
6
4
  * How long a hand-rolled `EventSource` waits before reconnecting, if one ever gets here.
7
5
  *
@@ -11,84 +9,22 @@ var HEARTBEAT_MS = 15e3;
11
9
  */
12
10
  var RETRY_MS = 864e5;
13
11
  /**
14
- * How much unread body may pile up before the run is stopped.
12
+ * Opens a run's Server-Sent Events response.
15
13
  *
16
- * A `write` that answers `false` has been buffered rather than sent, which is normal for a moment and a leak
17
- * forever: a peer that stopped reading — a phone that slept, a proxy that wedged — otherwise has the whole run's
18
- * output accumulated for it in memory. The socket says nothing, so the only signal is this one.
19
- */
20
- var MAX_BUFFERED_BYTES = 1e6;
21
- var encode = (frame) => `event: ${frame.event}\ndata: ${JSON.stringify(frame.data)}\n\n`;
22
- /** What the host has written but not yet handed to the socket. Node's own response reports it; the minimum raw
23
- * response this server accepts does not have to, and a host that cannot say simply never trips the cap. */
24
- var bufferedBytes = (raw) => {
25
- const { writableLength } = raw;
26
- return typeof writableLength === "number" ? writableLength : 0;
27
- };
28
- /**
29
- * Opens a Server-Sent Events response.
30
- *
31
- * Written straight to the RAW response, never through the response helpers: those compress the body, set a
32
- * Content-Length and end it in one go, which is precisely what a stream cannot do. `no-transform` says the same
33
- * thing to every proxy in between, and `X-Accel-Buffering: no` says it to nginx, which otherwise holds frames
34
- * until its buffer fills and turns a live stream into one late burst.
14
+ * The run's id travels on the response head rather than in a frame: a streaming step returns as soon as the stream
15
+ * OPENS — that is what makes it a stream — so anything it learns from a frame arrives after the flow has already
16
+ * carried on. The head is the one place a caller can read the id in time to cancel the run it just started.
35
17
  */
36
18
  var openStream = (raw, onAbort, runId) => {
37
- let open = true;
38
- raw.writeHead(200, {
39
- "Content-Type": "text/event-stream; charset=utf-8",
40
- "Cache-Control": "no-cache, no-transform",
41
- Connection: "keep-alive",
42
- "X-Accel-Buffering": "no",
43
- /**
44
- * The run's id, on the response head rather than in a frame.
45
- *
46
- * A streaming step returns as soon as the stream OPENS — that is what makes it a stream — so anything it
47
- * learns from a frame arrives after the flow has already carried on. The head is the one place a caller can
48
- * read the id in time to cancel the run it just started.
49
- */
50
- "X-Plitzi-Run-Id": runId
19
+ const stream = openEventStream(raw, {
20
+ onAbort,
21
+ headers: { "X-Plitzi-Run-Id": runId },
22
+ retryMs: RETRY_MS
51
23
  });
52
- raw.write(`retry: ${RETRY_MS}\n\n`);
53
- const heartbeat = setInterval(() => {
54
- if (!open) return;
55
- try {
56
- raw.write(": ping\n\n");
57
- } catch {
58
- open = false;
59
- clearInterval(heartbeat);
60
- onAbort();
61
- }
62
- }, HEARTBEAT_MS);
63
- const close = () => {
64
- if (!open) return;
65
- open = false;
66
- clearInterval(heartbeat);
67
- try {
68
- raw.end();
69
- } catch {}
70
- };
71
24
  return {
72
- send: (frame) => {
73
- if (!open) return;
74
- try {
75
- raw.write(encode(frame));
76
- if (bufferedBytes(raw) > MAX_BUFFERED_BYTES) {
77
- open = false;
78
- clearInterval(heartbeat);
79
- onAbort();
80
- try {
81
- raw.end();
82
- } catch {}
83
- }
84
- } catch {
85
- open = false;
86
- clearInterval(heartbeat);
87
- onAbort();
88
- }
89
- },
90
- close,
91
- isOpen: () => open
25
+ send: (frame) => stream.send(frame.event, frame.data),
26
+ close: stream.close,
27
+ isOpen: stream.isOpen
92
28
  };
93
29
  };
94
30
  /** Whether this caller asked for a stream. The negotiation is the client's, so a page that cannot read one never
@@ -1,5 +1,6 @@
1
- import { ActionRunError } from "../runtime/errors.js";
1
+ import { serverLog } from "../../../helpers/serverLog.js";
2
2
  import { findTriggerNode, triggerParams } from "../runtime/triggers.js";
3
+ import { ActionRunError } from "../runtime/errors.js";
3
4
  import { precheckRun } from "../runtime/precheck.js";
4
5
  import onAbort from "../../../helpers/onAbort.js";
5
6
  import { reportReject } from "../runtime/report.js";
@@ -75,7 +76,7 @@ var handleActionWebhook = async (deps) => {
75
76
  * one without a single line of it changing. Fail closed, and say which document to fix.
76
77
  */
77
78
  if (triggerHasStaleVerify(stepParams)) {
78
- console.error(`[Actions] webhook "${actionId}" in space ${spaceId} carries a signature check in a format nothing reads any more, so it is refused. Name the signing credential on the trigger step.`);
79
+ serverLog.error("Actions", `webhook "${actionId}" in space ${spaceId} carries a signature check in a format nothing reads any more, so it is refused. Name the signing credential on the trigger step.`);
79
80
  await reject("unverifiable", "The signature check is in a format nothing reads any more; name the signing credential on the trigger step");
80
81
  send(res, 503, { error: "Unavailable" });
81
82
  return;
@@ -99,7 +100,7 @@ var handleActionWebhook = async (deps) => {
99
100
  const secret = await resolveSecret(verify, spaceId, config.action?.lookups?.getCredential);
100
101
  const check = verifySignature(verify, secret, req.headers, rawBody);
101
102
  if (!check.ok) {
102
- console.warn(`[Actions] webhook "${actionId}" rejected: ${check.reason}`);
103
+ serverLog.warn("Actions", `webhook "${actionId}" rejected: ${check.reason}`);
103
104
  await reject("invalid_signature", check.reason);
104
105
  send(res, 401, { error: "Invalid signature" });
105
106
  return;
@@ -182,7 +183,7 @@ var handleActionWebhook = async (deps) => {
182
183
  status: result.status
183
184
  });
184
185
  } catch (error) {
185
- console.error("[Actions] webhook run failed:", error);
186
+ serverLog.error("Actions", "webhook run failed", error);
186
187
  send(res, 500, { accepted: false });
187
188
  } finally {
188
189
  releaseAbort();
@@ -1,5 +1,10 @@
1
1
  import { ActionEmailSender } from './runtime/email';
2
- import { ActionEmailConfig, ActionEntry, ActionLimits, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionRunStep, ActionTriggerType, ConnectorManifest, Environment, InteractionCallbackParam, InteractionNode, InteractionNodeStatus, SpaceRevision, SSRUser } from '@plitzi/sdk-shared';
2
+ import { FunctionsConfig } from '../functions/config';
3
+ import { SpaceFunctions } from '../functions/protocol';
4
+ import { KvChangeLifetime } from './runtime/kvChange';
5
+ import { KvListEntry, KvListPut, KvListPutOptions, KvListRange } from './runtime/kvList';
6
+ import { SpaceSigning } from './runtime/signing';
7
+ import { ActionEmailConfig, ActionJobQueue, ActionEntry, ActionLimits, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionRunStep, ActionTriggerType, ConnectorManifest, Environment, InteractionCallbackParam, InteractionNode, InteractionNodeStatus, SpaceRevision, SSRUser } from '@plitzi/sdk-shared';
3
8
  /** Resolved secret material, as the connector engine already models it. */
4
9
  export type ActionCredential = Record<string, string>;
5
10
  /**
@@ -31,7 +36,7 @@ export type ActionDbDriver = {
31
36
  /**
32
37
  * Where a deployment keeps the `kv` tasks' data — Redis, Memcached, a table, whatever it already runs.
33
38
  *
34
- * Deliberately the DUMBEST possible surface: five operations over strings, with no rule to obey. Everything that
39
+ * Deliberately the DUMBEST possible surface: six operations over strings, with no rule to obey. Everything that
35
40
  * decides how a counter behaves — the key prefixing, the JSON round trip, and the one rule a rate limit lives or
36
41
  * dies by — is `createKvStore`'s, above this. An adapter that had to remember "extend the TTL only when the
37
42
  * counter did not exist" would be an adapter each deployment gets to write that rule wrongly in.
@@ -48,6 +53,12 @@ export type ActionKvAdapter = {
48
53
  increment: (key: string, amount: number) => Promise<number>;
49
54
  /** Sets a lifetime on a key that already exists. When to call it is decided above, never here. */
50
55
  expire: (key: string, ttlSeconds: number) => Promise<void>;
56
+ /**
57
+ * Writes `next` only if the key still holds `expected` — or, with `expected` undefined, only if it holds nothing (a
58
+ * key past its lifetime holds nothing). Answers whether it wrote. Must be atomic: it is what lets two writers
59
+ * read, change and write the same value without one of them silently undoing the other.
60
+ */
61
+ swap: (key: string, expected: string | undefined, next: string, ttlSeconds?: number) => Promise<boolean>;
51
62
  };
52
63
  /**
53
64
  * The `kv` tasks' own view: values rather than strings, and a TTL that means what a caller expects.
@@ -60,6 +71,27 @@ export type ActionKvStore = {
60
71
  set: (key: string, value: unknown, ttlSeconds?: number) => Promise<void>;
61
72
  delete: (key: string) => Promise<void>;
62
73
  increment: (key: string, amount: number, ttlSeconds?: number) => Promise<number>;
74
+ /**
75
+ * Writes `next` only if the key still holds `expected` — the value `get` answered — or, with `expected` undefined,
76
+ * only if it holds nothing. Answers whether it wrote: read, change, and write back with this, and a writer that
77
+ * lost the race is told so instead of undoing the other.
78
+ */
79
+ swap: (key: string, expected: unknown, next: unknown, ttlSeconds?: number) => Promise<boolean>;
80
+ /**
81
+ * Puts `entry` in the list — replacing the one with its id — keeping the highest `keep` by score, and answers what
82
+ * that dropped, for whatever it named to be let go of too. A list has no lifetime: it lives until its entries are
83
+ * removed.
84
+ */
85
+ listPut: (list: string, entry: KvListEntry, options?: KvListPutOptions) => Promise<KvListPut>;
86
+ listRange: (list: string, range?: KvListRange) => Promise<KvListEntry[]>;
87
+ /** Takes the entry with `id` out of the list, and answers whether it was there. */
88
+ listRemove: (list: string, id: string) => Promise<boolean>;
89
+ /**
90
+ * Reads the key, hands its value to `change` and writes back what that answers — reading and asking again when
91
+ * somebody wrote in between, so no writer undoes another. `change` answering `undefined` writes nothing. Answers what
92
+ * was written. `lifetime` is seconds, or worked out from the value written.
93
+ */
94
+ change: <T>(key: string, change: (current: unknown) => T | undefined | Promise<T | undefined>, lifetime?: KvChangeLifetime<T>) => Promise<T | undefined>;
63
95
  };
64
96
  /** Re-exported so the module's files import one place. One type for actions and connectors: it is one concept. */
65
97
  export type { SpaceRevision } from '@plitzi/sdk-shared';
@@ -71,8 +103,23 @@ export type ActionLookups = {
71
103
  getAction: (spaceId: number, actionId: string, at?: SpaceRevision) => Promise<ActionEntry | undefined>;
72
104
  /** Only the builder's catalog, the MCP and the scheduler need the list; a page call never asks for it. */
73
105
  listActions?: (spaceId: number, at?: SpaceRevision) => Promise<ActionEntry[]>;
106
+ /**
107
+ * Which spaces have something scheduled, for the periodic reconcile.
108
+ *
109
+ * Optional, and a safety net rather than the mechanism: a deployment keeps the schedule rows current by calling
110
+ * `reconcile` whenever a space's actions change, and this is what catches the write that did not happen — a
111
+ * restore from backup, a row edited by hand, a deploy that missed a save. Absent, nothing reconciles on a timer
112
+ * and the rows are exactly as correct as the calls that wrote them.
113
+ */
114
+ listScheduledSpaces?: () => Promise<number[]>;
74
115
  getCredential?: (spaceId: number, identifier: string) => Promise<ActionCredential | undefined>;
75
116
  getConnector?: (spaceId: number, connectorId: string, at?: SpaceRevision) => Promise<ConnectorManifest | undefined>;
117
+ /**
118
+ * The space's own functions as of that revision — the bundle and what it declared when saved, run by the deployment's
119
+ * sandbox (`functions.runner`), or by the space's own runtime when it answers one with a `runner` of its own. Only
120
+ * asked when a run names a task the deployment does not have, or a request a path under `/api/`.
121
+ */
122
+ getFunctions?: (spaceId: number, at?: SpaceRevision) => Promise<SpaceFunctions | undefined>;
76
123
  };
77
124
  /**
78
125
  * The only door a task has to the outside world.
@@ -114,6 +161,41 @@ export type ActionTaskContext = {
114
161
  email: ActionEmailSender;
115
162
  /** Pushes a `data` frame to a streaming caller. A no-op when nobody negotiated a stream. */
116
163
  emit: (chunk: unknown) => void;
164
+ /**
165
+ * A line for whoever reads the run: kept on the step that said it (`logs`), redacted like the rest of it, and shown
166
+ * wherever the run is — the builder's Try, the run history.
167
+ */
168
+ log: (line: string) => void;
169
+ /**
170
+ * Publishes on one of this space's realtime channels, as the server — `undefined` when the server has none. What
171
+ * the `realtime.publish` task sends through.
172
+ */
173
+ publish?: (topic: string, type: string, data: unknown) => Promise<void>;
174
+ /**
175
+ * A grant for one topic of a `grant: true` channel of this space — what `realtime.grant` hands the page, once the
176
+ * flow has decided the visitor may be there. `undefined` when the server has no realtime channels.
177
+ */
178
+ grant?: (topic: string, ttlSeconds?: number) => Promise<string>;
179
+ /** Revokes `grant` for `topic` — or every grant for it, naming none — and lets go whoever is on it with one. */
180
+ revoke?: (topic: string, grant?: string) => Promise<void>;
181
+ /** Signs with the space's own key (`ActionsConfig.signingSecret`) — `undefined` when the deployment gave none. */
182
+ sign?: SpaceSigning['sign'];
183
+ verify?: SpaceSigning['verify'];
184
+ };
185
+ /** How the actions module reaches the server's realtime channels. Set by `createServer`, never by a deployment. */
186
+ export type ActionRealtime = {
187
+ publish: (space: {
188
+ spaceId: number;
189
+ environment: string;
190
+ }, topic: string, type: string, data: unknown) => Promise<void>;
191
+ grant: (space: {
192
+ spaceId: number;
193
+ environment: string;
194
+ }, topic: string, ttlSeconds?: number) => Promise<string>;
195
+ revoke: (space: {
196
+ spaceId: number;
197
+ environment: string;
198
+ }, topic: string, grant?: string) => Promise<void>;
117
199
  };
118
200
  /**
119
201
  * One step a server action can take.
@@ -147,8 +229,8 @@ export type ActionTaskRegistry = {
147
229
  /** What a deployment hands to `createServer` under `actions`. Absent → the module is never constructed. */
148
230
  export type ActionsConfig = {
149
231
  lookups: ActionLookups;
150
- /** Deployment-owned tasks, validated at boot against the built-ins. */
151
- tasks?: ActionTask<never>[];
232
+ /** Code of the server's own, and the sandbox for the spaces' — see `FunctionsConfig`. */
233
+ functions?: FunctionsConfig;
152
234
  /** Ceilings a per-action document may tighten but never exceed. */
153
235
  limits?: ActionLimits;
154
236
  /** How many runs may be in flight at once. Counted per space and for the process as a whole. */
@@ -159,6 +241,15 @@ export type ActionsConfig = {
159
241
  };
160
242
  /** Where the `kv` tasks keep things. Omitted → an in-process Map, which is per-replica by definition. */
161
243
  kv?: ActionKvAdapter;
244
+ /**
245
+ * Scheduled runs, and the durable queue they go through. See {@link ActionJobsConfig}.
246
+ *
247
+ * On by default wherever `lookups.listActions` is answerable, because a deployment that can list its actions can
248
+ * schedule them and the old behaviour — a `schedule` trigger that silently did nothing unless the deployment
249
+ * built a timer and a lock of its own — was a trigger the editor offered and the server did not honour. `false`
250
+ * turns it off for a replica that must only serve pages.
251
+ */
252
+ jobs?: ActionJobsConfig | false;
162
253
  /** Inbound webhooks are public, so they are counted per caller per minute. Default 60. */
163
254
  rateLimit?: {
164
255
  webhookPerMinute?: number;
@@ -199,6 +290,71 @@ export type ActionsConfig = {
199
290
  replayTtlMs?: number;
200
291
  };
201
292
  fetchImpl?: typeof fetch;
293
+ /** The server's realtime channels, for the `realtime.publish` task. Set by `createServer`. */
294
+ realtime?: ActionRealtime;
295
+ /**
296
+ * What each space's signatures are made from (`ctx.sign` / `ctx.verify` in its functions): at least 32 characters,
297
+ * the SAME on every replica — a key one signed is checked by whichever the next request reaches. Each space and
298
+ * environment signs with a key derived from it, so none can vouch for another. Absent, spaces sign nothing.
299
+ */
300
+ signingSecret?: string;
301
+ };
302
+ /**
303
+ * Scheduled runs: how they are produced, how many run at once, and where they are kept while they wait.
304
+ *
305
+ * Supplying nothing still schedules — over an in-process queue, which is correct for one replica and silently
306
+ * wrong for two, since each gets its own copy of every schedule. A deployment with more than one supplies a
307
+ * {@link ActionJobQueue} over a store they share.
308
+ */
309
+ export type ActionJobsConfig = {
310
+ /**
311
+ * Where jobs and schedules live. Omitted → this process's memory: nothing survives a restart, and a second
312
+ * replica produces the same fires all over again.
313
+ */
314
+ queue?: ActionJobQueue;
315
+ /**
316
+ * How many jobs this replica runs at once. Default 4; `0` makes it a producer that never consumes.
317
+ *
318
+ * The number that decides whether a backlog drains in minutes or hours, and it belongs to the deployment because
319
+ * only it knows what its flows do — a queue of five hundred HTTP calls wants a far higher number than a queue of
320
+ * five hundred renders. It never widens the run guards: `concurrency.perSpace` still caps one space's runs per
321
+ * replica, and jobs over that ceiling go back to the queue rather than failing.
322
+ */
323
+ workers?: number;
324
+ /** Whether this replica sweeps schedules into the queue at all. Default true. */
325
+ produce?: boolean;
326
+ /**
327
+ * The spaces this server schedules for, when it serves a known few.
328
+ *
329
+ * The self-hosted shape: one space, named once. A multi-tenant deployment answers the same question with
330
+ * {@link ActionLookups.listScheduledSpaces} instead, which wins when both are given. With neither, nothing tells
331
+ * the scheduler where to look and it says so at boot rather than sitting silent — a schedule that never fires is
332
+ * indistinguishable from a cron expression that is wrong.
333
+ */
334
+ spaces?: number[];
335
+ /** How often a free worker looks for a job. Default 1s. */
336
+ pollMs?: number;
337
+ /** How often this replica looks for due schedules. Default 15s. */
338
+ schedulePollMs?: number;
339
+ /**
340
+ * How long a claim is held before another replica may take the job over — the failover window. Default 30s,
341
+ * renewed every third of it while a job runs.
342
+ */
343
+ leaseMs?: number;
344
+ /** Attempts a scheduled job gets before it is left for an operator as `dead`. Default 3. */
345
+ maxAttempts?: number;
346
+ /** First retry delay, doubling per attempt, up to `maxMs`. Defaults to 30s and 15 minutes. */
347
+ backoff?: {
348
+ baseMs?: number;
349
+ maxMs?: number;
350
+ };
351
+ /** Which environment scheduled runs execute in. Default `main`. */
352
+ environment?: Environment;
353
+ /** How often schedules are re-derived from documents, where `listScheduledSpaces` allows it. Default 15 min. */
354
+ reconcileMs?: number;
355
+ /** Names this replica in the job history. Defaults to the pid and a random suffix. */
356
+ workerId?: string;
357
+ onError?: (error: unknown) => void;
202
358
  };
203
359
  /** Re-exported so the module's own files import one place, and a deployment writing an `onRun` or an `onReject`
204
360
  * sees the same shapes the module emits. */
@@ -241,4 +397,6 @@ export type ActionRunResult = {
241
397
  * anybody allowed to debug the page. The trace above is for authoring and development servers alone.
242
398
  */
243
399
  steps: ActionRunStep[];
400
+ /** Why the run failed, when a step said so for the caller (`ActionRefusal`). Absent for every other failure. */
401
+ error?: string;
244
402
  };
@@ -1,4 +1,4 @@
1
- import { assertOutboundAllowed } from "../../helpers/outboundGuard.js";
1
+ import { fetchOutbound } from "../../helpers/outboundGuard.js";
2
2
  import { getByPath } from "./getByPath.js";
3
3
  import { processTwig } from "@plitzi/sdk-shared/helpers/twigWrapper";
4
4
  import { BODYLESS_METHODS, DEFAULT_READ_ENDPOINT, EMPTY_RESPONSE_METHODS } from "@plitzi/sdk-shared/connectors";
@@ -150,7 +150,6 @@ var fetchConnectorRecords = async ({ manifest, endpoint = DEFAULT_READ_ENDPOINT,
150
150
  ...renderEntries(read.query ?? {}, variables),
151
151
  ...renderFilters(resolved, connection.operators, variables)
152
152
  }).forEach(([key, value]) => url.searchParams.set(key, value));
153
- await assertOutboundAllowed(url);
154
153
  const method = read.method ?? "GET";
155
154
  const headers = {
156
155
  ...applyAuth(connection, variables, url),
@@ -158,7 +157,7 @@ var fetchConnectorRecords = async ({ manifest, endpoint = DEFAULT_READ_ENDPOINT,
158
157
  };
159
158
  const sendsBody = !BODYLESS_METHODS.includes(method);
160
159
  if (sendsBody) headers["Content-Type"] = "application/json";
161
- const response = await fetchImpl(url.toString(), {
160
+ const response = await fetchOutbound(fetchImpl, url, {
162
161
  method,
163
162
  headers,
164
163
  body: sendsBody ? JSON.stringify(renderEntries(read.body ?? {}, variables)) : void 0
@@ -202,13 +201,12 @@ var writeConnectorRecord = async ({ manifest, credential = {}, action, resource,
202
201
  };
203
202
  const url = new URL(render(operation.path, variables), connection.baseUrl);
204
203
  Object.entries(renderEntries(operation.query ?? {}, variables)).forEach(([key, value]) => url.searchParams.set(key, value));
205
- await assertOutboundAllowed(url);
206
204
  const headers = {
207
205
  ...applyAuth(connection, variables, url),
208
206
  ...renderEntries(operation.headers ?? {}, variables)
209
207
  };
210
208
  headers["Content-Type"] = "application/json";
211
- const response = await fetchImpl(url.toString(), {
209
+ const response = await fetchOutbound(fetchImpl, url, {
212
210
  method: operation.method,
213
211
  headers,
214
212
  body: BODYLESS_METHODS.includes(operation.method) ? void 0 : JSON.stringify(wrapBody(values, operation.bodyPath))
@@ -0,0 +1,22 @@
1
+ import { FunctionsProblem } from '@plitzi/sdk-shared';
2
+ /** A space's functions source: its files under `functions/`, by path (`index.ts`, `lib/feed.ts`). */
3
+ export type FunctionsSource = Record<string, string>;
4
+ /** One bundle, built from a source: a single web-standard ES module whose default export is the definition. */
5
+ export type FunctionsBuild = {
6
+ code: string;
7
+ bytes: number;
8
+ };
9
+ export declare class FunctionsBuildError extends Error {
10
+ readonly problems: FunctionsProblem[];
11
+ constructor(problems: FunctionsProblem[]);
12
+ }
13
+ /** The file a space's functions start from. */
14
+ export declare const FUNCTIONS_ENTRY = "index.ts";
15
+ /** The most a bundle may weigh: well under the smallest provider a runner may be (Workers take 3 MB compressed). */
16
+ export declare const MAX_FUNCTIONS_BYTES = 1000000;
17
+ /**
18
+ * Builds a space's functions into one bundle — the only way code reaches a runner, so what runs is always what the
19
+ * source says. Web-standard and self-contained: the space's own files, and the contract; a Node built-in or any other
20
+ * package is refused with where it was imported, because no runner could provide it.
21
+ */
22
+ export declare const buildFunctions: (source: FunctionsSource) => Promise<FunctionsBuild>;