@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
@@ -1,6 +1,6 @@
1
+ import path from "node:path";
1
2
  import { fileURLToPath } from "node:url";
2
3
  import fs from "node:fs";
3
- import path from "node:path";
4
4
  import ejs from "ejs";
5
5
  //#region src/modules/ssr/template.ts
6
6
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -122,18 +122,21 @@
122
122
  <noscript>You need to enable JavaScript to run this app.</noscript>
123
123
  <div id="plitzi" class="plitzi-root-container"><%- locals.html || '' %></div>
124
124
  <% if (!locals.ssrOnly) { %>
125
+ <%# The payload is data, so it travels as JSON: parsing it as a JavaScript literal cost the browser several times
126
+ what JSON.parse does, on megabytes of it. Escaped by the server — no `<` reaches this block. %>
127
+ <script type="application/json" id="plitzi-ssr-data"><%- locals.offlineData || '{}' %></script>
125
128
  <script type="module">
126
129
  import { render } from '<%= locals.jsPath || '' %>';
127
130
  <% const activePlugins = (locals.plugins || []).filter(p => p.js); %>
128
- <% if (activePlugins.length > 0) { %>
129
131
  <% for (const plugin of activePlugins) { %>
130
132
  import { default as <%= plugin.varName %> } from '<%= plugin.js %>';
131
133
  <% } %>
132
134
  const __plitziPlugins = { <%- activePlugins.map(p => `'${p.keyName}': {component: ${p.varName}, props: ${JSON.stringify(p.props)}, clientOnly: ${p.ssr === false}}`).join(', ') %> };
133
- render('plitzi', <%- locals.offlineData || '{}' %>, __plitziPlugins, <%= locals.debugMode ? true : false %>, true);
134
- <% } else { %>
135
- render('plitzi', <%- locals.offlineData || '{}' %>, {}, <%= locals.debugMode ? true : false %>, true);
136
- <% } %>
135
+ const __plitziData = document.getElementById('plitzi-ssr-data');
136
+ const __plitziParams = JSON.parse(__plitziData.textContent);
137
+ // Read once: the page would otherwise hold the space twice, as this text and as what it was parsed into.
138
+ __plitziData.remove();
139
+ render('plitzi', __plitziParams, __plitziPlugins, <%= locals.debugMode ? true : false %>, true);
137
140
  </script>
138
141
  <% } %>
139
142
  </body>
package/dist/mysql.d.ts CHANGED
@@ -31,7 +31,7 @@ export { createMysqlStore, mysqlSchemaStatements } from './modules/mysql';
31
31
  * createServer({ action: { lookups, kv: createMysqlKv({ pool }), jobs: { queue: createMysqlJobQueue({ pool }) } } });
32
32
  * ```
33
33
  */
34
- export { createMysqlJobQueue, createMysqlKv, mysqlJobSchemaStatements } from './modules/mysql/jobs';
34
+ export { createMysqlJobQueue, createMysqlKv, mysqlJobSchemaStatements, mysqlJobSchemaUpgrades } from './modules/mysql/jobs';
35
35
  export type { MysqlJobQueue, MysqlJobQueueOptions, MysqlKvOptions } from './modules/mysql/jobs';
36
36
  export { SCHEMA_VERSION, TABLE_NAMES, tableNames } from './modules/mysql';
37
37
  export type { AccountSeed, MysqlAdmin, MysqlConfig, IdentityStore, LinkedIdentity, MysqlStore, SessionStore, SessionSummary, SpaceTokenSeed, TableKey, Tables } from './modules/mysql';
package/dist/mysql.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TABLE_NAMES, tableNames } from "./modules/mysql/config.js";
2
2
  import { SCHEMA_VERSION } from "./modules/mysql/schema.js";
3
3
  import { createMysqlStore, mysqlSchemaStatements } from "./modules/mysql/index.js";
4
- import { mysqlJobSchemaStatements } from "./modules/mysql/jobs/schema.js";
4
+ import { mysqlJobSchemaStatements, mysqlJobSchemaUpgrades } from "./modules/mysql/jobs/schema.js";
5
5
  import { createMysqlJobQueue } from "./modules/mysql/jobs/jobQueue.js";
6
6
  import { createMysqlKv } from "./modules/mysql/jobs/kv.js";
7
- export { SCHEMA_VERSION, TABLE_NAMES, createMysqlJobQueue, createMysqlKv, createMysqlStore, mysqlJobSchemaStatements, mysqlSchemaStatements, tableNames };
7
+ export { SCHEMA_VERSION, TABLE_NAMES, createMysqlJobQueue, createMysqlKv, createMysqlStore, mysqlJobSchemaStatements, mysqlJobSchemaUpgrades, mysqlSchemaStatements, tableNames };
package/dist/oauth.js CHANGED
@@ -1,10 +1,10 @@
1
+ import { dropPending, getAccess, getClient, getPending, putCode, putPending } from "./core/oauth/records.js";
1
2
  import { AUTHORIZATION_SERVER_PATH, AUTHORIZE_PATH, PROTECTED_RESOURCE_PATH, REGISTER_PATH, TOKEN_PATH, authorizationServerMetadata, protectedResourceMetadata } from "./core/oauth/metadata.js";
2
3
  import { randomId, verifyChallenge } from "./core/oauth/pkce.js";
3
- import { dropPending, getAccess, getClient, getPending, putCode, putPending } from "./core/oauth/records.js";
4
4
  import { redirectToSignIn, redirectWithCode, redirectWithError, sendErrorJson, sendJson } from "./core/oauth/respond.js";
5
+ import { handleRegister } from "./core/oauth/register.js";
5
6
  import { handleAuthorizeStart, handleAuthorizeSubmit } from "./core/oauth/authorize.js";
6
7
  import { bearerOf, sendChallenge } from "./core/oauth/challenge.js";
7
- import { handleRegister } from "./core/oauth/register.js";
8
8
  import { handleRevoke, handleToken } from "./core/oauth/token.js";
9
9
  import { createOAuthGuardStage, createOAuthStage } from "./core/http/stages/oauth.js";
10
10
  export { AUTHORIZATION_SERVER_PATH, AUTHORIZE_PATH, PROTECTED_RESOURCE_PATH, REGISTER_PATH, TOKEN_PATH, authorizationServerMetadata, bearerOf, createOAuthGuardStage, createOAuthStage, dropPending, getAccess, getClient, getPending, handleAuthorizeStart, handleAuthorizeSubmit, handleRegister, handleRevoke, handleToken, protectedResourceMetadata, putCode, putPending, randomId, redirectToSignIn, redirectWithCode, redirectWithError, sendChallenge, sendErrorJson, sendJson, verifyChallenge };
@@ -1,6 +1,7 @@
1
+ import { writeFileAtomic } from "../helpers/atomicFile.js";
1
2
  import path from "node:path";
2
- import fs from "node:fs/promises";
3
3
  import esbuild from "esbuild";
4
+ import fs from "node:fs/promises";
4
5
  //#region src/plugins/compile.ts
5
6
  var EXTERNAL = [
6
7
  "react",
@@ -29,7 +30,8 @@ var ASSET_LOADERS = {
29
30
  ".woff2": "dataurl"
30
31
  };
31
32
  /**
32
- * Everything that went into the bundle, so a dev server can tell when any of it has moved on.
33
+ * Everything that went into the bundle, so a server can tell when any of it has moved on: a dev server as it is
34
+ * edited, and any server — a deployment — when it finds a bundle built from something else (its content digest).
33
35
  *
34
36
  * The entry file is one file and a plugin is a directory: a component edited beside its `index.ts` leaves the entry's
35
37
  * timestamp exactly where it was, and a watcher looking only at that never rebuilds. esbuild already knows the answer
@@ -52,10 +54,13 @@ var compilePlugin = async (jsPath, outDir, devMode = false) => {
52
54
  minify: !devMode,
53
55
  splitting: false,
54
56
  logLevel: "warning",
55
- metafile: devMode
57
+ metafile: true,
58
+ write: false
56
59
  });
60
+ await fs.mkdir(outDir, { recursive: true });
61
+ await Promise.all(result.outputFiles.map((output) => writeFileAtomic(output.path, output.contents)));
57
62
  return {
58
- hasCSS: await fs.access(path.join(outDir, "index.css")).then(() => true).catch(() => false),
63
+ hasCSS: result.outputFiles.some((output) => path.basename(output.path) === "index.css"),
59
64
  inputs: sourceInputs(result.metafile)
60
65
  };
61
66
  };
@@ -1,13 +1,13 @@
1
+ import { copyFileAtomic, writeFileAtomic } from "../helpers/atomicFile.js";
1
2
  import path from "node:path";
2
- import fs from "node:fs/promises";
3
3
  //#region src/plugins/copy.ts
4
4
  var copyPlugin = async (src, destDir, filename) => {
5
5
  const dest = path.join(destDir, filename);
6
6
  if (src.startsWith("http://") || src.startsWith("https://")) {
7
7
  const res = await fetch(src);
8
8
  if (!res.ok) throw new Error(`[SSR] Plugin fetch failed ${src}: ${res.status}`);
9
- await fs.writeFile(dest, await res.text(), "utf-8");
10
- } else await fs.copyFile(src, dest);
9
+ await writeFileAtomic(dest, await res.text());
10
+ } else await copyFileAtomic(src, dest);
11
11
  };
12
12
  //#endregion
13
13
  export { copyPlugin };
@@ -14,9 +14,18 @@ export declare class PluginManager {
14
14
  hasPlugin(name: string): boolean;
15
15
  register(name: string, source: PluginSource): void;
16
16
  /**
17
- * Registers a plugin only if it is not yet known under its effective key.
18
- * Returns the effective key (`name@version` when version is set, `name` otherwise)
19
- * so the caller can pass it directly to getEntries().
17
+ * Keeps a source a render names, and returns the key to pass to getEntries(): `name@version+<identity>`, or
18
+ * `name@<identity>` without a version.
19
+ *
20
+ * The identity is what the source IS — where its files are, how they are served, the props it carries — because a
21
+ * name and a version are only what its author said about it. Keyed on those alone, the first source to arrive held
22
+ * the key for as long as the process ran: a plugin published again under the same version kept its old, now missing
23
+ * URLs, and two spaces each with a `board@1.0.0` of their own were served whichever this process had met first.
24
+ * Worked out from the source rather than handed out in order of arrival, so every worker names one source the same
25
+ * way — the key is also the folder a built bundle is written to, and all of them share it.
26
+ *
27
+ * Never taken as what a bare name means: {@link resolveKey} answers for the plugins this server was set up with, not
28
+ * for whichever space rendered last.
20
29
  */
21
30
  ensure(name: string, source: PluginSource): string;
22
31
  /**
@@ -46,6 +55,18 @@ export declare class PluginManager {
46
55
  * `checkedAt` is stamped on the cached entry rather than kept in a second map, so it cannot outlive what it is about.
47
56
  */
48
57
  private isStaleInMemory;
58
+ /**
59
+ * Whether what a bundle on disk was built from reads differently now — asked once, when a process first finds the
60
+ * bundle, in production as much as in development.
61
+ *
62
+ * A version names a release, and a release is only as good as whoever bumps it: a deployment rebuilt from new source
63
+ * under the same version found last deployment's bundle in its cache folder and served it, with nothing anywhere
64
+ * saying so. The content decides instead. A bundle written before digests were recorded has none, and is built again
65
+ * once. What this server does not build from files — a download, a CDN, a component — is its version's business.
66
+ */
67
+ private contentChanged;
68
+ /** The local files a bundle is built from: what the compiler reported, or the files it was copied from. */
69
+ private inputsOf;
49
70
  private isStale;
50
71
  /**
51
72
  * The bundle's URL, stamped with when it was built.
@@ -68,10 +89,21 @@ export declare class PluginManager {
68
89
  */
69
90
  private toRemoteEntry;
70
91
  private isWebUrl;
92
+ /**
93
+ * Builds every registered plugin now rather than on first use. A primary does it before starting its workers, so
94
+ * the workers find each one built — instead of all of them compiling the same plugin into the same folder at once.
95
+ */
96
+ prepareAll(): Promise<void>;
71
97
  prepare(name: string): Promise<PluginEntry | null>;
72
98
  private build;
73
99
  getEntries(names: string[]): Promise<PluginEntry[]>;
74
100
  getComponents(): Record<string, unknown>;
101
+ /**
102
+ * Drops what this process remembers of a plugin — its entry, its failure, which version its name means — and
103
+ * leaves the disk alone. What an invalidation elsewhere in the fleet does here: that process removes the files,
104
+ * and each of the others only has to stop pointing at them.
105
+ */
106
+ forget(name?: string, version?: string): void;
75
107
  invalidate(name?: string, version?: string): Promise<void>;
76
108
  destroy(): void;
77
109
  private readMeta;
@@ -1,13 +1,34 @@
1
+ import { serverLog } from "../helpers/serverLog.js";
2
+ import { writeFileAtomic } from "../helpers/atomicFile.js";
1
3
  import { compilePlugin } from "./compile.js";
2
4
  import { copyPlugin } from "./copy.js";
3
5
  import { detectAction, isComponentSource } from "./detect.js";
4
6
  import { assertPluginSources } from "./validate.js";
7
+ import { createHash } from "node:crypto";
5
8
  import path from "node:path";
6
9
  import fs from "node:fs/promises";
7
10
  //#region src/plugins/manager.ts
8
11
  var META_FILE = "meta.json";
9
12
  var DEFAULT_TTL_MS = 6048e5;
10
13
  var DEFAULT_CACHE_DIR = ".sdk-plugins";
14
+ /** One hash over every input's path and content — a file gone counts as changed, like a file edited. */
15
+ var digestOf = async (files) => {
16
+ const hash = createHash("sha256");
17
+ for (const file of [...files].sort()) {
18
+ hash.update(file);
19
+ hash.update("\0");
20
+ hash.update(await fs.readFile(file).catch(() => Buffer.from("\0missing")));
21
+ }
22
+ return hash.digest("hex");
23
+ };
24
+ /**
25
+ * Whether a key is this plugin — every version of it, or with `version` that one release — counting the sources a
26
+ * render named under it (`name@1.0.0+<identity>`, see {@link PluginManager.ensure}).
27
+ */
28
+ var isKeyOf = (key, name, version) => {
29
+ if (version) return key === `${name}@${version}` || key.startsWith(`${name}@${version}+`);
30
+ return key === name || key.startsWith(`${name}@`);
31
+ };
11
32
  /**
12
33
  * How often a dev server re-asks whether a cached plugin is still current.
13
34
  *
@@ -48,13 +69,28 @@ var PluginManager = class {
48
69
  this.nameIndex.set(baseName, name);
49
70
  }
50
71
  /**
51
- * Registers a plugin only if it is not yet known under its effective key.
52
- * Returns the effective key (`name@version` when version is set, `name` otherwise)
53
- * so the caller can pass it directly to getEntries().
72
+ * Keeps a source a render names, and returns the key to pass to getEntries(): `name@version+<identity>`, or
73
+ * `name@<identity>` without a version.
74
+ *
75
+ * The identity is what the source IS — where its files are, how they are served, the props it carries — because a
76
+ * name and a version are only what its author said about it. Keyed on those alone, the first source to arrive held
77
+ * the key for as long as the process ran: a plugin published again under the same version kept its old, now missing
78
+ * URLs, and two spaces each with a `board@1.0.0` of their own were served whichever this process had met first.
79
+ * Worked out from the source rather than handed out in order of arrival, so every worker names one source the same
80
+ * way — the key is also the folder a built bundle is written to, and all of them share it.
81
+ *
82
+ * Never taken as what a bare name means: {@link resolveKey} answers for the plugins this server was set up with, not
83
+ * for whichever space rendered last.
54
84
  */
55
85
  ensure(name, source) {
56
- const key = source.version ? `${name}@${source.version}` : name;
57
- if (!(key in this.plugins)) this.register(key, source);
86
+ const identity = createHash("sha256").update(JSON.stringify([
87
+ source.js,
88
+ source.css,
89
+ isComponentSource(source) ? void 0 : source.action,
90
+ source.props
91
+ ])).digest("hex").slice(0, 12);
92
+ const key = `${name}@${source.version ? `${source.version}+` : ""}${identity}`;
93
+ if (!(key in this.plugins)) this.plugins[key] = source;
58
94
  return key;
59
95
  }
60
96
  /**
@@ -102,10 +138,34 @@ var PluginManager = class {
102
138
  inputs: cached.inputs
103
139
  }, source);
104
140
  }
141
+ /**
142
+ * Whether what a bundle on disk was built from reads differently now — asked once, when a process first finds the
143
+ * bundle, in production as much as in development.
144
+ *
145
+ * A version names a release, and a release is only as good as whoever bumps it: a deployment rebuilt from new source
146
+ * under the same version found last deployment's bundle in its cache folder and served it, with nothing anywhere
147
+ * saying so. The content decides instead. A bundle written before digests were recorded has none, and is built again
148
+ * once. What this server does not build from files — a download, a CDN, a component — is its version's business.
149
+ */
150
+ async contentChanged(meta, source) {
151
+ const inputs = this.inputsOf(source, meta.inputs ?? []);
152
+ if (inputs.length === 0) return false;
153
+ return meta.digest !== await digestOf(inputs);
154
+ }
155
+ /** The local files a bundle is built from: what the compiler reported, or the files it was copied from. */
156
+ inputsOf(source, compiled) {
157
+ if (isComponentSource(source) || source.action === "download" || source.action === "cdn") return [];
158
+ if (compiled.length > 0) return compiled;
159
+ return [source.js, source.css].filter((file) => typeof file === "string" && file !== "" && !/^https?:\/\//.test(file));
160
+ }
105
161
  async isStale(meta, source) {
106
162
  if (!this.devMode || !source.js || /^https?:\/\//.test(source.js) || isComponentSource(source)) return false;
107
163
  const watched = meta.inputs?.length ? meta.inputs : [source.js];
108
- return (await Promise.all(watched.map((file) => fs.stat(file).then((stats) => stats.mtimeMs).catch(() => 0)))).some((modifiedAt) => modifiedAt > meta.compiledAt);
164
+ if (meta.inputs?.length) {
165
+ const entry = await fs.realpath(source.js).catch(() => path.resolve(source.js));
166
+ if (!meta.inputs.includes(entry)) return true;
167
+ }
168
+ return (await Promise.all(watched.map((file) => fs.stat(file).then((stats) => stats.mtimeMs).catch(() => Number.POSITIVE_INFINITY)))).some((modifiedAt) => modifiedAt > meta.compiledAt);
109
169
  }
110
170
  /**
111
171
  * The bundle's URL, stamped with when it was built.
@@ -153,6 +213,13 @@ var PluginManager = class {
153
213
  isWebUrl(s) {
154
214
  return s.startsWith("/") || s.startsWith("http://") || s.startsWith("https://");
155
215
  }
216
+ /**
217
+ * Builds every registered plugin now rather than on first use. A primary does it before starting its workers, so
218
+ * the workers find each one built — instead of all of them compiling the same plugin into the same folder at once.
219
+ */
220
+ async prepareAll() {
221
+ await Promise.all(Object.keys(this.plugins).map((key) => this.prepare(key)));
222
+ }
156
223
  async prepare(name) {
157
224
  const key = this.resolveKey(name) ?? name;
158
225
  if (this.failed.has(key)) return null;
@@ -172,28 +239,28 @@ var PluginManager = class {
172
239
  * does not even restart the watcher.
173
240
  */
174
241
  if (!await this.isStaleInMemory(cached, source)) return cached.entry;
175
- console.log(`[SSR] Plugin "${key}" source changed since it was built, rebuilding…`);
242
+ serverLog.info("SSR", `Plugin "${key}" source changed since it was built, rebuilding…`);
176
243
  this.mem.delete(key);
177
244
  await fs.rm(this.pluginDir(key), {
178
245
  recursive: true,
179
246
  force: true
180
247
  });
181
248
  } else {
182
- console.warn(`[SSR] Plugin "${key}" cache invalidated: output file missing, rebuilding…`);
249
+ serverLog.warn("SSR", `Plugin "${key}" cache invalidated: output file missing, rebuilding…`);
183
250
  this.mem.delete(key);
184
251
  }
185
252
  }
186
253
  const meta = await this.readMeta(key);
187
254
  if (meta) {
188
255
  const sourceVersion = source.version;
189
- if (await this.isStale(meta, source)) {
190
- console.log(`[SSR] Plugin "${key}" source changed since it was built, rebuilding…`);
256
+ if (await this.isStale(meta, source) || await this.contentChanged(meta, source)) {
257
+ serverLog.info("SSR", `Plugin "${key}" source changed since it was built, rebuilding…`);
191
258
  await fs.rm(this.pluginDir(key), {
192
259
  recursive: true,
193
260
  force: true
194
261
  });
195
262
  } else if (sourceVersion && meta.version !== sourceVersion) {
196
- console.log(`[SSR] Plugin "${key}" version changed (${meta.version ?? "none"} → ${sourceVersion}), rebuilding…`);
263
+ serverLog.info("SSR", `Plugin "${key}" version changed (${meta.version ?? "none"} → ${sourceVersion}), rebuilding…`);
197
264
  await fs.rm(this.pluginDir(key), {
198
265
  recursive: true,
199
266
  force: true
@@ -225,7 +292,7 @@ var PluginManager = class {
225
292
  const cssPath = source.css;
226
293
  const action = isComponentSource(source) ? source.js ? detectAction(source.js) : void 0 : source.action ?? detectAction(source.js);
227
294
  if (!jsPath || !action) return this.toEntry(name, false, void 0, source.props);
228
- console.log(`[SSR] Plugin "${name}" building (${action}: ${jsPath})…`);
295
+ serverLog.info("SSR", `Plugin "${name}" building (${action}: ${jsPath})…`);
229
296
  try {
230
297
  let cssUrl;
231
298
  let buildInputs = [];
@@ -243,12 +310,12 @@ var PluginManager = class {
243
310
  } else if (action === "download") {
244
311
  const jsRes = await fetch(jsPath);
245
312
  if (!jsRes.ok) throw new Error(`HTTP ${jsRes.status} downloading ${jsPath}`);
246
- await fs.writeFile(path.join(dir, "index.js"), await jsRes.text());
313
+ await writeFileAtomic(path.join(dir, "index.js"), await jsRes.text());
247
314
  if (cssPath) {
248
315
  if (cssPath.startsWith("http://") || cssPath.startsWith("https://")) {
249
316
  const cssRes = await fetch(cssPath);
250
317
  if (!cssRes.ok) throw new Error(`HTTP ${cssRes.status} downloading ${cssPath}`);
251
- await fs.writeFile(path.join(dir, "index.css"), await cssRes.text());
318
+ await writeFileAtomic(path.join(dir, "index.css"), await cssRes.text());
252
319
  } else if (this.isWebUrl(cssPath)) cssUrl = cssPath;
253
320
  else await copyPlugin(cssPath, dir, "index.css");
254
321
  cssUrl = `${this.urlPrefix}/${name}/index.css`;
@@ -264,10 +331,12 @@ var PluginManager = class {
264
331
  }
265
332
  }
266
333
  const compiledAt = Date.now();
334
+ const inputs = this.inputsOf(source, buildInputs);
267
335
  await this.writeMeta(name, {
268
336
  compiledAt,
269
337
  version: source.version,
270
- inputs: buildInputs
338
+ inputs: buildInputs,
339
+ ...inputs.length > 0 ? { digest: await digestOf(inputs) } : {}
271
340
  });
272
341
  if (cssUrl?.startsWith(this.urlPrefix)) cssUrl = this.assetUrl(name, "index.css", compiledAt);
273
342
  const entry = this.toEntry(name, true, cssUrl, source.props, compiledAt);
@@ -276,10 +345,10 @@ var PluginManager = class {
276
345
  entry,
277
346
  inputs: buildInputs
278
347
  });
279
- console.log(`[SSR] Plugin "${name}" ready → ${entry.js}`);
348
+ serverLog.info("SSR", `Plugin "${name}" ready → ${entry.js}`);
280
349
  return entry;
281
350
  } catch (err) {
282
- console.error(`[SSR] Plugin "${name}" build failed (js: ${source.js ?? "none"}):`, err);
351
+ serverLog.error("SSR", `Plugin "${name}" build failed (js: ${source.js ?? "none"})`, err);
283
352
  this.failed.add(name);
284
353
  return null;
285
354
  }
@@ -293,41 +362,43 @@ var PluginManager = class {
293
362
  for (const [name, source] of Object.entries(this.plugins)) if (isComponentSource(source)) out[name.replace(/@[^@]*$/, "")] = source.component;
294
363
  return out;
295
364
  }
296
- async invalidate(name, version) {
365
+ /**
366
+ * Drops what this process remembers of a plugin — its entry, its failure, which version its name means — and
367
+ * leaves the disk alone. What an invalidation elsewhere in the fleet does here: that process removes the files,
368
+ * and each of the others only has to stop pointing at them.
369
+ */
370
+ forget(name, version) {
297
371
  if (!name) {
298
372
  this.mem.clear();
299
373
  this.failed.clear();
300
374
  this.nameIndex.clear();
301
- await fs.rm(this.outputDir, {
302
- recursive: true,
303
- force: true
304
- });
305
375
  return;
306
376
  }
307
- if (version) {
308
- const key = `${name}@${version}`;
377
+ const keysToEvict = /* @__PURE__ */ new Set();
378
+ for (const key of [
379
+ ...Object.keys(this.plugins),
380
+ ...this.mem.keys(),
381
+ ...this.failed
382
+ ]) if (isKeyOf(key, name, version)) keysToEvict.add(key);
383
+ for (const key of keysToEvict) {
309
384
  this.mem.delete(key);
310
385
  this.failed.delete(key);
311
- if (this.nameIndex.get(name) === key) this.nameIndex.delete(name);
312
- await fs.rm(this.pluginDir(key), {
386
+ }
387
+ const indexed = this.nameIndex.get(name);
388
+ if (indexed !== void 0 && isKeyOf(indexed, name, version)) this.nameIndex.delete(name);
389
+ }
390
+ async invalidate(name, version) {
391
+ this.forget(name, version);
392
+ if (!name) {
393
+ await fs.rm(this.outputDir, {
313
394
  recursive: true,
314
395
  force: true
315
396
  });
316
397
  return;
317
398
  }
318
- const prefix = `${name}@`;
319
- const keysToEvict = /* @__PURE__ */ new Set();
320
- keysToEvict.add(name);
321
- for (const key of Object.keys(this.plugins)) if (key.startsWith(prefix)) keysToEvict.add(key);
322
- for (const key of this.mem.keys()) if (key.startsWith(prefix)) keysToEvict.add(key);
323
- for (const key of keysToEvict) {
324
- this.mem.delete(key);
325
- this.failed.delete(key);
326
- }
327
- this.nameIndex.delete(name);
328
399
  try {
329
400
  const entries = await fs.readdir(this.outputDir);
330
- await Promise.all(entries.filter((e) => e === name || e.startsWith(prefix)).map((e) => fs.rm(path.join(this.outputDir, e), {
401
+ await Promise.all(entries.filter((entry) => isKeyOf(entry, name, version)).map((entry) => fs.rm(path.join(this.outputDir, entry), {
331
402
  recursive: true,
332
403
  force: true
333
404
  })));
@@ -347,7 +418,7 @@ var PluginManager = class {
347
418
  }
348
419
  }
349
420
  async writeMeta(name, meta) {
350
- await fs.writeFile(path.join(this.pluginDir(name), META_FILE), JSON.stringify(meta), "utf-8");
421
+ await writeFileAtomic(path.join(this.pluginDir(name), META_FILE), JSON.stringify(meta));
351
422
  }
352
423
  async fileExists(p) {
353
424
  return fs.access(p).then(() => true).catch(() => false);
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Space runtimes: a space's own server code run as code of its own, beside the platform that serves the space — for
3
+ * what the sandbox's functions cannot be (Node, its dependencies, connections that stay open, endpoints that stream).
4
+ * The contract a runtime module is written against, the host that runs one for the platform, how one is packed to
5
+ * travel, and the stages that serve one: on a server of its own (`serveRuntime`), or forwarded to (`createRuntimeProxyStage`).
6
+ */
7
+ export { defineRuntime, endpointFor, endpointProblem } from './modules/runtime/contract';
8
+ export type { SpaceRuntime, SpaceRuntimeContext, SpaceRuntimeEndpoint, SpaceRuntimeParts } from './modules/runtime/contract';
9
+ export { RUNTIME_DESCRIBE_PATH, startSpaceRuntime } from './modules/runtime/host';
10
+ export type { SpaceRuntimeDescription, SpaceRuntimeHost, SpaceRuntimeHostOptions } from './modules/runtime/host';
11
+ export { inspectRuntime, loadRuntime, MAX_RUNTIME_BUNDLE_BYTES, packRuntime, runtimeBundleId } from './modules/runtime/bundle';
12
+ export { reachSpaceInside } from './modules/runtime/inside';
13
+ export { createRuntimeRunner } from './modules/runtime/runner';
14
+ export { createRuntimeProxyStage, runtimeEndpointsStage, serveRuntime } from './modules/runtime/stages';
15
+ export type { RuntimeProxyConfig, RuntimeTarget, ServedRuntime } from './modules/runtime/stages';
@@ -0,0 +1,7 @@
1
+ import { defineRuntime, endpointFor, endpointProblem } from "./modules/runtime/contract.js";
2
+ import { reachSpaceInside } from "./modules/runtime/inside.js";
3
+ import { createRuntimeRunner } from "./modules/runtime/runner.js";
4
+ import { RUNTIME_DESCRIBE_PATH, startSpaceRuntime } from "./modules/runtime/host.js";
5
+ import { MAX_RUNTIME_BUNDLE_BYTES, inspectRuntime, loadRuntime, packRuntime, runtimeBundleId } from "./modules/runtime/bundle.js";
6
+ import { createRuntimeProxyStage, runtimeEndpointsStage, serveRuntime } from "./modules/runtime/stages.js";
7
+ export { MAX_RUNTIME_BUNDLE_BYTES, RUNTIME_DESCRIBE_PATH, createRuntimeProxyStage, createRuntimeRunner, defineRuntime, endpointFor, endpointProblem, inspectRuntime, loadRuntime, packRuntime, reachSpaceInside, runtimeBundleId, runtimeEndpointsStage, serveRuntime, startSpaceRuntime };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plitzi/sdk-server",
3
- "version": "0.37.2",
3
+ "version": "0.37.4",
4
4
  "license": "AGPL-3.0",
5
5
  "files": [
6
6
  "dist",
@@ -54,7 +54,23 @@
54
54
  "types": "./dist/actions.d.ts",
55
55
  "import": "./dist/actions.js",
56
56
  "default": "./dist/actions.js"
57
- }
57
+ },
58
+ "./functions": {
59
+ "types": "./dist/functions.d.ts",
60
+ "import": "./dist/functions.js",
61
+ "default": "./dist/functions.js"
62
+ },
63
+ "./functions-runner": {
64
+ "types": "./dist/functionsRunner.d.ts",
65
+ "import": "./dist/functionsRunner.js",
66
+ "default": "./dist/functionsRunner.js"
67
+ },
68
+ "./runtime": {
69
+ "types": "./dist/runtime.d.ts",
70
+ "import": "./dist/runtime.js",
71
+ "default": "./dist/runtime.js"
72
+ },
73
+ "./functions-api.d.ts": "./dist/functions-api.d.ts"
58
74
  },
59
75
  "repository": {
60
76
  "type": "https",
@@ -63,20 +79,30 @@
63
79
  "type": "module",
64
80
  "sideEffects": false,
65
81
  "dependencies": {
66
- "@plitzi/plitzi-sdk": "0.37.2",
67
- "@plitzi/sdk-shared": "0.37.2",
82
+ "@plitzi/plitzi-sdk": "0.37.4",
83
+ "@plitzi/sdk-shared": "0.37.4",
68
84
  "ejs": "^6.0.1",
69
85
  "esbuild": "^0.28.2",
70
86
  "jsonwebtoken": "^9.0.3",
71
- "nodemailer": "^10.0.10"
87
+ "nodemailer": "^10.0.10",
88
+ "undici": "^8.11.2",
89
+ "ws": "^8.21.1"
72
90
  },
73
91
  "peerDependencies": {
92
+ "core-js": "^3.50.0",
93
+ "isolated-vm": "^7.0.1",
74
94
  "mongodb": "^6 || ^7",
75
95
  "mysql2": "^3",
76
96
  "react": "^19",
77
97
  "react-dom": "^19"
78
98
  },
79
99
  "peerDependenciesMeta": {
100
+ "core-js": {
101
+ "optional": true
102
+ },
103
+ "isolated-vm": {
104
+ "optional": true
105
+ },
80
106
  "mongodb": {
81
107
  "optional": true
82
108
  },
@@ -85,22 +111,27 @@
85
111
  }
86
112
  },
87
113
  "devDependencies": {
114
+ "@microsoft/api-extractor": "^7.59.2",
88
115
  "@types/ejs": "^3.1.5",
89
116
  "@types/jsonwebtoken": "^9.0.10",
90
117
  "@types/node": "^26.6.2",
91
118
  "@types/nodemailer": "^8.0.2",
92
119
  "@types/react": "^19.3.0",
120
+ "@types/ws": "^8.18.1",
93
121
  "@vitejs/plugin-react": "^6.1.1",
94
122
  "@vitest/coverage-v8": "^5.0.1",
123
+ "core-js": "^3.50.0",
95
124
  "eslint": "^9.39.5",
96
125
  "eslint-plugin-import": "^2.32.0",
126
+ "ioredis": "^6.0.0",
127
+ "isolated-vm": "^7.0.1",
97
128
  "mongodb": "^7.6.0",
98
129
  "mysql2": "^3.24.4",
99
130
  "react": "^19.3.0",
100
131
  "react-dom": "^19.3.0",
101
132
  "tsx": "^4.23.15",
102
133
  "typescript": "^6.0.3",
103
- "vite": "^8.3.0",
134
+ "vite": "^8.3.1",
104
135
  "vite-plugin-dts": "^5.1.1",
105
136
  "vitest": "^5.0.1"
106
137
  },
@@ -110,8 +141,8 @@
110
141
  "start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx dev/main.ts",
111
142
  "start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch dev/main.ts",
112
143
  "start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect dev/main.ts",
113
- "build:dev": "vite build --mode development",
114
- "build:prod": "vite build",
144
+ "build:dev": "vite build --mode development && node scripts/functions-api.mjs",
145
+ "build:prod": "vite build && node scripts/functions-api.mjs",
115
146
  "lint": "TIMING=1 eslint ./src ./dev",
116
147
  "typecheck": "tsc -p tsconfig.app.json --noEmit",
117
148
  "test": "vitest run",