@belte/belte 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/CHANGELOG.md +313 -0
  2. package/LICENSE +21 -0
  3. package/README.md +559 -0
  4. package/bin/belte.ts +183 -0
  5. package/package.json +110 -0
  6. package/src/App.svelte +31 -0
  7. package/src/appEntry.ts +151 -0
  8. package/src/assets/app.html +14 -0
  9. package/src/belteResolverPlugin.ts +858 -0
  10. package/src/build.ts +147 -0
  11. package/src/buildCli.ts +129 -0
  12. package/src/buildDisconnected.ts +122 -0
  13. package/src/bundleApp.ts +149 -0
  14. package/src/bundleDisconnectedEntry.ts +17 -0
  15. package/src/cliEntry.ts +25 -0
  16. package/src/clientBuildPlugins.ts +41 -0
  17. package/src/clientEntry.ts +7 -0
  18. package/src/compile.ts +64 -0
  19. package/src/controlServerWorker.ts +422 -0
  20. package/src/dedupeSveltePlugin.ts +66 -0
  21. package/src/devEntry.ts +169 -0
  22. package/src/discoveryEntry.ts +81 -0
  23. package/src/lib/browser/applyStreamedResolution.ts +33 -0
  24. package/src/lib/browser/cacheEntryFromSnapshot.ts +48 -0
  25. package/src/lib/browser/flushUnresolvedPlaceholders.ts +16 -0
  26. package/src/lib/browser/installStreamingPlaceholders.ts +32 -0
  27. package/src/lib/browser/openResolveStream.ts +42 -0
  28. package/src/lib/browser/page.svelte.ts +258 -0
  29. package/src/lib/browser/pageStreamController.ts +17 -0
  30. package/src/lib/browser/refetchPlaceholder.ts +12 -0
  31. package/src/lib/browser/remoteProxy.ts +37 -0
  32. package/src/lib/browser/socketChannel.ts +192 -0
  33. package/src/lib/browser/socketProxy.ts +57 -0
  34. package/src/lib/browser/startClient.ts +153 -0
  35. package/src/lib/browser/subscribe.ts +131 -0
  36. package/src/lib/browser/types/Errors.ts +9 -0
  37. package/src/lib/browser/types/Layouts.ts +7 -0
  38. package/src/lib/browser/types/Pages.ts +7 -0
  39. package/src/lib/browser/types/StreamingDeferred.ts +9 -0
  40. package/src/lib/bundle/BundleMenu.ts +11 -0
  41. package/src/lib/bundle/BundleMenuItem.ts +24 -0
  42. package/src/lib/bundle/BundleWindow.ts +36 -0
  43. package/src/lib/bundle/WEBVIEW_BUILD_REVISION.ts +9 -0
  44. package/src/lib/bundle/WEBVIEW_VERSION.ts +7 -0
  45. package/src/lib/bundle/bindConnectedFlag.ts +29 -0
  46. package/src/lib/bundle/bindRequestNavigate.ts +31 -0
  47. package/src/lib/bundle/buildWebviewLib.ts +111 -0
  48. package/src/lib/bundle/disconnected.css +9 -0
  49. package/src/lib/bundle/disconnected.svelte +386 -0
  50. package/src/lib/bundle/ensureWebviewLib.ts +20 -0
  51. package/src/lib/bundle/exitWithParent.ts +28 -0
  52. package/src/lib/bundle/infoPlist.ts +46 -0
  53. package/src/lib/bundle/installDownloads.ts +24 -0
  54. package/src/lib/bundle/installMacMenu.ts +39 -0
  55. package/src/lib/bundle/listenLocalControlServer.ts +19 -0
  56. package/src/lib/bundle/native/belteMenu.mm +422 -0
  57. package/src/lib/bundle/native/webview.h +4557 -0
  58. package/src/lib/bundle/onMenu.ts +41 -0
  59. package/src/lib/bundle/openWebview.ts +104 -0
  60. package/src/lib/bundle/pngToIcns.ts +47 -0
  61. package/src/lib/bundle/probeBelteServer.ts +34 -0
  62. package/src/lib/bundle/resolveServerBinary.ts +12 -0
  63. package/src/lib/bundle/resolveWebviewLib.ts +53 -0
  64. package/src/lib/bundle/serverBinaryFilename.ts +8 -0
  65. package/src/lib/bundle/signMacApp.ts +35 -0
  66. package/src/lib/bundle/spawnEmbeddedServer.ts +65 -0
  67. package/src/lib/bundle/stableLocalPort.ts +19 -0
  68. package/src/lib/bundle/waitForServer.ts +23 -0
  69. package/src/lib/bundle/webviewCachePath.ts +23 -0
  70. package/src/lib/bundle/webviewLibName.ts +11 -0
  71. package/src/lib/cli/connectToServer.ts +23 -0
  72. package/src/lib/cli/createClient.ts +170 -0
  73. package/src/lib/cli/dispatchCommand.ts +71 -0
  74. package/src/lib/cli/loadEnvFromBinaryDir.ts +16 -0
  75. package/src/lib/cli/parseArgvForRpc.ts +97 -0
  76. package/src/lib/cli/printHelp.ts +119 -0
  77. package/src/lib/cli/printSessionHelp.ts +27 -0
  78. package/src/lib/cli/printSessionStatus.ts +21 -0
  79. package/src/lib/cli/printTrimmed.ts +8 -0
  80. package/src/lib/cli/printValue.ts +10 -0
  81. package/src/lib/cli/resolveCliTarget.ts +48 -0
  82. package/src/lib/cli/runCli.ts +139 -0
  83. package/src/lib/cli/runSession.ts +105 -0
  84. package/src/lib/cli/startLocalInstance.ts +14 -0
  85. package/src/lib/cli/tokenizeLine.ts +51 -0
  86. package/src/lib/cli/types/CliManifest.ts +9 -0
  87. package/src/lib/cli/types/CliManifestEntry.ts +17 -0
  88. package/src/lib/cli/types/CliTarget.ts +13 -0
  89. package/src/lib/mcp/annotationsForMethod.ts +29 -0
  90. package/src/lib/mcp/createMcpResourceServer.ts +101 -0
  91. package/src/lib/mcp/createMcpServer.ts +42 -0
  92. package/src/lib/mcp/dispatchMcpRequest.ts +146 -0
  93. package/src/lib/mcp/mcpResourceServerSlot.ts +18 -0
  94. package/src/lib/mcp/mcpSurface.ts +265 -0
  95. package/src/lib/mcp/toolResultFromResponse.ts +66 -0
  96. package/src/lib/mcp/types/JsonRpcRequest.ts +12 -0
  97. package/src/lib/mcp/types/JsonRpcResponse.ts +20 -0
  98. package/src/lib/mcp/types/McpResourceContents.ts +10 -0
  99. package/src/lib/mcp/types/McpResourceDescriptor.ts +6 -0
  100. package/src/lib/mcp/types/McpResourceServer.ts +12 -0
  101. package/src/lib/mcp/types/McpServer.ts +9 -0
  102. package/src/lib/mcp/types/McpServerOptions.ts +16 -0
  103. package/src/lib/server/AppModule.ts +33 -0
  104. package/src/lib/server/DELETE.ts +9 -0
  105. package/src/lib/server/GET.ts +9 -0
  106. package/src/lib/server/HEAD.ts +9 -0
  107. package/src/lib/server/PATCH.ts +9 -0
  108. package/src/lib/server/POST.ts +9 -0
  109. package/src/lib/server/PUT.ts +9 -0
  110. package/src/lib/server/agent.ts +76 -0
  111. package/src/lib/server/appDataDir.ts +15 -0
  112. package/src/lib/server/cli/buildEnvContent.ts +19 -0
  113. package/src/lib/server/cli/createTarGz.ts +76 -0
  114. package/src/lib/server/cli/handleCliDownload.ts +153 -0
  115. package/src/lib/server/cli/handleCliInstall.ts +37 -0
  116. package/src/lib/server/cli/installScript.ts +29 -0
  117. package/src/lib/server/cli/maxSourceMtime.ts +26 -0
  118. package/src/lib/server/cookies.ts +29 -0
  119. package/src/lib/server/env.ts +50 -0
  120. package/src/lib/server/error.ts +70 -0
  121. package/src/lib/server/json.ts +28 -0
  122. package/src/lib/server/jsonl.ts +46 -0
  123. package/src/lib/server/prompts/definePrompt.ts +20 -0
  124. package/src/lib/server/prompts/promptRegistry.ts +9 -0
  125. package/src/lib/server/prompts/registerPrompt.ts +6 -0
  126. package/src/lib/server/prompts/renderPromptTemplate.ts +16 -0
  127. package/src/lib/server/prompts/types/Prompt.ts +13 -0
  128. package/src/lib/server/prompts/types/PromptOptions.ts +12 -0
  129. package/src/lib/server/prompts/types/PromptRegistryEntry.ts +13 -0
  130. package/src/lib/server/prompts/types/PromptRoutes.ts +10 -0
  131. package/src/lib/server/redirect.ts +42 -0
  132. package/src/lib/server/request.ts +18 -0
  133. package/src/lib/server/rpc/defineVerb.ts +133 -0
  134. package/src/lib/server/rpc/dispatchVerbInProcess.ts +46 -0
  135. package/src/lib/server/rpc/findVerbByCommandName.ts +18 -0
  136. package/src/lib/server/rpc/parseArgs.ts +95 -0
  137. package/src/lib/server/rpc/registerVerb.ts +6 -0
  138. package/src/lib/server/rpc/types/RemoteHandler.ts +27 -0
  139. package/src/lib/server/rpc/types/RemoteRoutes.ts +13 -0
  140. package/src/lib/server/rpc/types/TypedResponse.ts +18 -0
  141. package/src/lib/server/rpc/types/VerbHelper.ts +68 -0
  142. package/src/lib/server/rpc/types/VerbRegistryEntry.ts +29 -0
  143. package/src/lib/server/rpc/unprocessed.ts +14 -0
  144. package/src/lib/server/rpc/verbRegistry.ts +11 -0
  145. package/src/lib/server/runtime/DEFAULT_PORT.ts +6 -0
  146. package/src/lib/server/runtime/DEV_REBUILD_MESSAGE.ts +4 -0
  147. package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +29 -0
  148. package/src/lib/server/runtime/acceptsZstd.ts +8 -0
  149. package/src/lib/server/runtime/buildOpenApiSpec.ts +106 -0
  150. package/src/lib/server/runtime/cacheControlForAsset.ts +22 -0
  151. package/src/lib/server/runtime/containsTraversal.ts +37 -0
  152. package/src/lib/server/runtime/createAssetHeaderCache.ts +35 -0
  153. package/src/lib/server/runtime/createPublicAssetServer.ts +63 -0
  154. package/src/lib/server/runtime/createRouteDispatcher.ts +100 -0
  155. package/src/lib/server/runtime/createServer.ts +692 -0
  156. package/src/lib/server/runtime/devReloadResponse.ts +35 -0
  157. package/src/lib/server/runtime/disableIdleTimeoutForStream.ts +27 -0
  158. package/src/lib/server/runtime/envSchemaStore.ts +15 -0
  159. package/src/lib/server/runtime/findOpenPort.ts +35 -0
  160. package/src/lib/server/runtime/getActiveServer.ts +6 -0
  161. package/src/lib/server/runtime/globToPathSet.ts +29 -0
  162. package/src/lib/server/runtime/inProcessServer.ts +20 -0
  163. package/src/lib/server/runtime/internalErrorResponse.ts +25 -0
  164. package/src/lib/server/runtime/isCrossOriginUpgrade.ts +19 -0
  165. package/src/lib/server/runtime/listenOnOpenPort.ts +36 -0
  166. package/src/lib/server/runtime/logExposedSurfaces.ts +162 -0
  167. package/src/lib/server/runtime/mimeForExtension.ts +20 -0
  168. package/src/lib/server/runtime/parseIdleTimeout.ts +10 -0
  169. package/src/lib/server/runtime/parsePort.ts +11 -0
  170. package/src/lib/server/runtime/registryManifests.ts +66 -0
  171. package/src/lib/server/runtime/requestContext.ts +5 -0
  172. package/src/lib/server/runtime/resolveStreamResponse.ts +29 -0
  173. package/src/lib/server/runtime/runWithRequestScope.ts +57 -0
  174. package/src/lib/server/runtime/safeJsonForScript.ts +17 -0
  175. package/src/lib/server/runtime/serializeCacheSnapshot.ts +45 -0
  176. package/src/lib/server/runtime/serverSlot.ts +13 -0
  177. package/src/lib/server/runtime/setActiveServer.ts +6 -0
  178. package/src/lib/server/runtime/snapshotEntryFromCache.ts +81 -0
  179. package/src/lib/server/runtime/streamCacheResolutions.ts +37 -0
  180. package/src/lib/server/runtime/streamFromIterator.ts +86 -0
  181. package/src/lib/server/runtime/streamStash.ts +64 -0
  182. package/src/lib/server/runtime/types/Assets.ts +1 -0
  183. package/src/lib/server/runtime/types/RequestStore.ts +27 -0
  184. package/src/lib/server/runtime/withResponseDefaults.ts +24 -0
  185. package/src/lib/server/server.ts +32 -0
  186. package/src/lib/server/socket.ts +31 -0
  187. package/src/lib/server/sockets/createSocketDispatcher.ts +311 -0
  188. package/src/lib/server/sockets/defineSocket.ts +167 -0
  189. package/src/lib/server/sockets/lookupSocket.ts +6 -0
  190. package/src/lib/server/sockets/recentHistory.ts +11 -0
  191. package/src/lib/server/sockets/registerSocket.ts +6 -0
  192. package/src/lib/server/sockets/socketOperations.ts +35 -0
  193. package/src/lib/server/sockets/socketRegistry.ts +9 -0
  194. package/src/lib/server/sockets/types/Socket.ts +21 -0
  195. package/src/lib/server/sockets/types/SocketClientFrame.ts +18 -0
  196. package/src/lib/server/sockets/types/SocketOperation.ts +22 -0
  197. package/src/lib/server/sockets/types/SocketOptions.ts +22 -0
  198. package/src/lib/server/sockets/types/SocketRegistryEntry.ts +17 -0
  199. package/src/lib/server/sockets/types/SocketRoutes.ts +10 -0
  200. package/src/lib/server/sockets/types/SocketServerFrame.ts +15 -0
  201. package/src/lib/server/sse.ts +53 -0
  202. package/src/lib/shared/BELTE_PACKAGE_NAME.ts +7 -0
  203. package/src/lib/shared/CACHE_CONTROL_VALUES.ts +16 -0
  204. package/src/lib/shared/HttpError.ts +19 -0
  205. package/src/lib/shared/RESOLVE_STREAM_PATH.ts +7 -0
  206. package/src/lib/shared/STREAMING_CONTENT_TYPES.ts +11 -0
  207. package/src/lib/shared/activeCacheStore.ts +20 -0
  208. package/src/lib/shared/appDataDir.ts +34 -0
  209. package/src/lib/shared/belteImportName.ts +44 -0
  210. package/src/lib/shared/browserClientFlags.ts +10 -0
  211. package/src/lib/shared/buildRpcRequest.ts +70 -0
  212. package/src/lib/shared/bundleLayout.ts +36 -0
  213. package/src/lib/shared/bundled.ts +34 -0
  214. package/src/lib/shared/cache.ts +559 -0
  215. package/src/lib/shared/cacheStoreSlot.ts +16 -0
  216. package/src/lib/shared/canonicalJson.ts +63 -0
  217. package/src/lib/shared/carriesBodyArgs.ts +13 -0
  218. package/src/lib/shared/clearLastConnection.ts +7 -0
  219. package/src/lib/shared/commandNameForUrl.ts +17 -0
  220. package/src/lib/shared/createCacheStore.ts +75 -0
  221. package/src/lib/shared/createPushIterator.ts +93 -0
  222. package/src/lib/shared/createRemoteFunction.ts +99 -0
  223. package/src/lib/shared/decodeResponse.ts +47 -0
  224. package/src/lib/shared/detectTarget.ts +27 -0
  225. package/src/lib/shared/exeSuffix.ts +9 -0
  226. package/src/lib/shared/exitOnBuildFailure.ts +17 -0
  227. package/src/lib/shared/extraForwardHeaders.ts +16 -0
  228. package/src/lib/shared/fileStem.ts +9 -0
  229. package/src/lib/shared/findExportCallSite.ts +479 -0
  230. package/src/lib/shared/forwardHeaders.ts +41 -0
  231. package/src/lib/shared/getRemoteMeta.ts +5 -0
  232. package/src/lib/shared/globalCacheStore.ts +15 -0
  233. package/src/lib/shared/globalCacheStoreSlot.ts +14 -0
  234. package/src/lib/shared/importNamesToStrip.ts +13 -0
  235. package/src/lib/shared/invalidateEvent.ts +11 -0
  236. package/src/lib/shared/isCompileTarget.ts +15 -0
  237. package/src/lib/shared/isDebugEnabled.ts +23 -0
  238. package/src/lib/shared/isModuleNotFound.ts +16 -0
  239. package/src/lib/shared/isReadOnlyMethod.ts +14 -0
  240. package/src/lib/shared/isStreamingResponse.ts +11 -0
  241. package/src/lib/shared/jsonSchemaForPromptArguments.ts +29 -0
  242. package/src/lib/shared/jsonSchemaForSchema.ts +32 -0
  243. package/src/lib/shared/jsonlErrorFrame.ts +24 -0
  244. package/src/lib/shared/keyForRemoteCall.ts +29 -0
  245. package/src/lib/shared/lastConnectionPath.ts +7 -0
  246. package/src/lib/shared/loadEnvFile.ts +17 -0
  247. package/src/lib/shared/loadEnvFromDataDir.ts +15 -0
  248. package/src/lib/shared/loadSvelteConfig.ts +18 -0
  249. package/src/lib/shared/log.ts +104 -0
  250. package/src/lib/shared/manifestModule.ts +39 -0
  251. package/src/lib/shared/memoizeByKey.ts +24 -0
  252. package/src/lib/shared/nearestLayoutPrefix.ts +36 -0
  253. package/src/lib/shared/normalizeTarget.ts +10 -0
  254. package/src/lib/shared/pageUrlForFile.ts +14 -0
  255. package/src/lib/shared/parseBoundedEnvInt.ts +20 -0
  256. package/src/lib/shared/parseEnv.ts +30 -0
  257. package/src/lib/shared/parsePromptMarkdown.ts +34 -0
  258. package/src/lib/shared/parseRouteSegments.ts +22 -0
  259. package/src/lib/shared/prepareRpcModule.ts +59 -0
  260. package/src/lib/shared/prepareSocketModule.ts +49 -0
  261. package/src/lib/shared/programNameForPackage.ts +14 -0
  262. package/src/lib/shared/promptNameForFile.ts +10 -0
  263. package/src/lib/shared/queryStringFromArgs.ts +27 -0
  264. package/src/lib/shared/readEnvFile.ts +15 -0
  265. package/src/lib/shared/readLastConnection.ts +18 -0
  266. package/src/lib/shared/readPackageJson.ts +9 -0
  267. package/src/lib/shared/recordRemoteMeta.ts +5 -0
  268. package/src/lib/shared/remoteMetaStore.ts +16 -0
  269. package/src/lib/shared/resolveClientFlags.ts +20 -0
  270. package/src/lib/shared/responseErrorText.ts +9 -0
  271. package/src/lib/shared/rpcUrlForFile.ts +19 -0
  272. package/src/lib/shared/runningAsStandaloneBinary.ts +13 -0
  273. package/src/lib/shared/serializeEnv.ts +18 -0
  274. package/src/lib/shared/setCacheStoreResolver.ts +6 -0
  275. package/src/lib/shared/setGlobalCacheStoreResolver.ts +6 -0
  276. package/src/lib/shared/socketNameForFile.ts +11 -0
  277. package/src/lib/shared/sseErrorFrame.ts +29 -0
  278. package/src/lib/shared/streamResponse.ts +169 -0
  279. package/src/lib/shared/stripImport.ts +27 -0
  280. package/src/lib/shared/subscribableFromResponse.ts +51 -0
  281. package/src/lib/shared/toBunRoutePattern.ts +28 -0
  282. package/src/lib/shared/types/CacheEntry.ts +63 -0
  283. package/src/lib/shared/types/CacheInvalidation.ts +9 -0
  284. package/src/lib/shared/types/CacheOptions.ts +33 -0
  285. package/src/lib/shared/types/CacheSnapshot.ts +16 -0
  286. package/src/lib/shared/types/CacheSnapshotEntry.ts +15 -0
  287. package/src/lib/shared/types/CacheStore.ts +32 -0
  288. package/src/lib/shared/types/ClientFlags.ts +11 -0
  289. package/src/lib/shared/types/CompileTarget.ts +6 -0
  290. package/src/lib/shared/types/HttpVerb.ts +1 -0
  291. package/src/lib/shared/types/LastConnection.ts +9 -0
  292. package/src/lib/shared/types/PromptArgument.ts +12 -0
  293. package/src/lib/shared/types/RawRemoteFunction.ts +13 -0
  294. package/src/lib/shared/types/RemoteFunction.ts +42 -0
  295. package/src/lib/shared/types/StandardSchemaV1.ts +57 -0
  296. package/src/lib/shared/types/StreamedResolution.ts +10 -0
  297. package/src/lib/shared/types/StreamingPlaceholder.ts +13 -0
  298. package/src/lib/shared/types/Subscribable.ts +15 -0
  299. package/src/lib/shared/types/SvelteConfig.ts +5 -0
  300. package/src/lib/shared/withJsonSchema.ts +20 -0
  301. package/src/lib/shared/writeLastConnection.ts +13 -0
  302. package/src/lib/shared/writeRoutesDts.ts +67 -0
  303. package/src/lib/test/clearVerbRegistry.ts +11 -0
  304. package/src/lib/test/createTestClient.ts +78 -0
  305. package/src/preload.ts +20 -0
  306. package/src/scaffold.ts +92 -0
  307. package/src/serverBuildPlugins.ts +25 -0
  308. package/src/serverEntry.ts +94 -0
  309. package/src/sveltePlugin.ts +58 -0
  310. package/src/tailwindStylePreprocessor.ts +62 -0
  311. package/template/bunfig.toml +4 -0
  312. package/template/package.json +19 -0
  313. package/template/src/app.ts +23 -0
  314. package/template/src/browser/app.css +21 -0
  315. package/template/src/browser/app.html +24 -0
  316. package/template/src/browser/pages/about/page.svelte +5 -0
  317. package/template/src/browser/pages/layout.svelte +26 -0
  318. package/template/src/browser/pages/page.svelte +20 -0
  319. package/template/src/bundle/icon.png +0 -0
  320. package/template/src/cli/banner.txt +3 -0
  321. package/template/src/cli/footer.txt +1 -0
  322. package/template/src/server/config.ts +17 -0
  323. package/template/src/server/rpc/getHello.ts +35 -0
  324. package/template/svelte.config.js +12 -0
  325. package/template/tsconfig.json +18 -0
  326. package/tsconfig.app.json +16 -0
@@ -0,0 +1,15 @@
1
+ /*
2
+ Wire format for a single cached response shipped from SSR to client hydration.
3
+ Only GET/DELETE entries with a textual Content-Type are emitted — POST/PUT
4
+ bodies can't be reconstructed without shipping the original request body,
5
+ and binary bodies don't survive a JSON round-trip.
6
+ */
7
+ export type CacheSnapshotEntry = {
8
+ key: string
9
+ url: string
10
+ method: 'GET' | 'DELETE'
11
+ status: number
12
+ statusText: string
13
+ headers: Array<[string, string]>
14
+ body: string
15
+ }
@@ -0,0 +1,32 @@
1
+ import type { CacheEntry } from './CacheEntry.ts'
2
+
3
+ /*
4
+ Cache map paired with a Svelte-aware per-key subscriber. Calling
5
+ `subscribe(key)` from inside a tracking scope ($derived / $effect) registers
6
+ that scope to re-run when the entry is invalidated; called outside tracking
7
+ it's a no-op. Subscribers live for the lifetime of the store: the server
8
+ uses a fresh store per request (so subscribers die with the response), the
9
+ client uses a single module-level store (so subscribers persist for the tab).
10
+
11
+ `trackLifecycle` is the store-wide counterpart used by cache.pending: unlike a
12
+ keyed read it matches many entries (or all), so it re-derives by scanning
13
+ entries and only needs one "in-flight membership changed" signal. Reading it in
14
+ a tracking scope re-runs that scope whenever any call starts, settles, or is
15
+ evicted.
16
+ */
17
+ export type CacheStore = {
18
+ entries: Map<string, CacheEntry>
19
+ events: EventTarget
20
+ subscribe: (key: string) => void
21
+ trackLifecycle: () => void
22
+ /*
23
+ Keys dropped by a (policy-less) invalidate, awaiting their next read. The
24
+ drop erases the entry, so the next cache() call is a cold miss with no memory
25
+ it followed an invalidate; this set carries that signal across the gap so the
26
+ replacement entry is flagged a reload (cache.refreshing true) rather than a
27
+ first-ever load. Consumed when that entry is created; a key invalidated but
28
+ never re-read just lingers (bounded by distinct such keys; the server's
29
+ request-scoped store discards it with the response).
30
+ */
31
+ pendingRefresh: Set<string>
32
+ }
@@ -0,0 +1,11 @@
1
+ /*
2
+ Which client surfaces a verb or socket is exposed to. Browser is the
3
+ historical default; MCP and CLI flip on automatically when the
4
+ declaration carries a Standard Schema (the schema is what makes the
5
+ non-browser surfaces safe to advertise). Explicit values always win.
6
+ */
7
+ export type ClientFlags = {
8
+ browser: boolean
9
+ mcp: boolean
10
+ cli: boolean
11
+ }
@@ -0,0 +1,6 @@
1
+ export type CompileTarget =
2
+ | 'bun-darwin-arm64'
3
+ | 'bun-darwin-x64'
4
+ | 'bun-linux-arm64'
5
+ | 'bun-linux-x64'
6
+ | 'bun-windows-x64'
@@ -0,0 +1 @@
1
+ export type HttpVerb = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD'
@@ -0,0 +1,9 @@
1
+ /*
2
+ The launcher/CLI-owned record of the last connection, kept in the data dir so it
3
+ survives relaunch and is readable before any window or session opens. It records
4
+ the *intent*, not a concrete embedded URL — an embedded server picks a fresh port
5
+ each launch, so only `{ kind: 'embedded' }` is durable; a remote connection keeps
6
+ its url. resolveLaunchTarget / resolveCliTarget read it; /connect and /start write
7
+ it; /disconnect clears it.
8
+ */
9
+ export type LastConnection = { kind: 'embedded' } | { kind: 'url'; url: string }
@@ -0,0 +1,12 @@
1
+ /*
2
+ A single declared argument of a markdown prompt, parsed from the file's
3
+ YAML frontmatter `arguments:` list. `name` is the placeholder the body
4
+ interpolates via `{{name}}`; `description` + `required` feed the argument
5
+ list MCP advertises in `prompts/list`. Build-time only — markdown prompts
6
+ carry no runtime schema object, so this drives the generated JSON Schema.
7
+ */
8
+ export type PromptArgument = {
9
+ name: string
10
+ description?: string
11
+ required?: boolean
12
+ }
@@ -0,0 +1,13 @@
1
+ import type { HttpVerb } from './HttpVerb.ts'
2
+
3
+ /*
4
+ Bare-response remote function — same call shape as RemoteFunction but
5
+ resolves to the underlying Response without Content-Type decode and
6
+ without throwing on non-2xx. Produced as `.raw` on every RemoteFunction
7
+ so callers that need status / headers / body streaming or want to
8
+ implement custom error handling can opt out of the decode.
9
+ */
10
+ export type RawRemoteFunction<Args> = ((args: Args | FormData) => Promise<Response>) & {
11
+ readonly method: HttpVerb
12
+ readonly url: string
13
+ }
@@ -0,0 +1,42 @@
1
+ import type { ClientFlags } from './ClientFlags.ts'
2
+ import type { HttpVerb } from './HttpVerb.ts'
3
+ import type { RawRemoteFunction } from './RawRemoteFunction.ts'
4
+ import type { Subscribable } from './Subscribable.ts'
5
+
6
+ /*
7
+ Remote function reference produced by GET/POST/... inside an `$rpc/**`
8
+ module and consumed by rpc dispatch, cache(), SSR auto-hydration, and
9
+ direct calls. Same callable signature on server and client — the bundler
10
+ swaps the implementation for browser builds.
11
+
12
+ The plain call resolves to the decoded body shape (sniffed from
13
+ Content-Type) and throws HttpError on non-2xx. `.raw` is a sibling
14
+ RemoteFunction whose call resolves to the underlying Response — same
15
+ method, same url, same args, no decode. Pass `fn.raw` to cache() to
16
+ memoise raw Responses against the same cache key as `fn` (both share one
17
+ stored entry — the decode just happens on the way out for callers of
18
+ `fn`). `.stream(args)` returns an iterable view of the Response body:
19
+ SSE / JSONL handlers yield each frame; non-streaming handlers yield the
20
+ decoded body once then complete. The result is a Subscribable, so it
21
+ can be passed to subscribe() and shared across reactive consumers.
22
+ For sustained broadcast / pub-sub use the `belte/server/socket` primitive —
23
+ HTTP rpc isn't the place for long-lived multi-publisher subscriptions.
24
+ `.fetch(req)` is the framework's request-dispatch entry point — used by
25
+ the router to invoke the handler from an incoming HTTP request, not
26
+ for user code.
27
+ */
28
+ /*
29
+ A body verb (POST/PUT/PATCH) also accepts a FormData in place of typed args:
30
+ buildRpcRequest ships it as a multipart body and the server splits text fields
31
+ into args (still schema-validated) and File parts into files(). FormData is
32
+ stringly-typed, so this is the upload escape hatch — typed object args remain
33
+ the default for everything else.
34
+ */
35
+ export type RemoteFunction<Args, Return> = ((args: Args | FormData) => Promise<Return>) & {
36
+ readonly method: HttpVerb
37
+ readonly url: string
38
+ readonly clients: ClientFlags
39
+ readonly raw: RawRemoteFunction<Args>
40
+ stream(args?: Args | FormData): Subscribable<Return>
41
+ fetch(request: Request): Promise<Response>
42
+ }
@@ -0,0 +1,57 @@
1
+ /*
2
+ Mirror of the Standard Schema v1 spec interface (standardschema.dev). Any
3
+ library that implements the spec — zod, valibot, arktype, etc. — produces
4
+ values whose `~standard` property structurally matches this shape, so users
5
+ can pass their existing schemas to verb helpers without an adapter.
6
+
7
+ Kept inline (no `@standard-schema/spec` dep) because the spec is type-only
8
+ and tiny; adding a package for ~30 lines of interface would be churn. The
9
+ namespace pattern below is the spec's own convention — `InferInput` /
10
+ `InferOutput` ride along the same export.
11
+ */
12
+ export interface StandardSchemaV1<Input = unknown, Output = Input> {
13
+ readonly '~standard': StandardSchemaV1.Props<Input, Output>
14
+ }
15
+
16
+ // biome-ignore lint/style/useNamingConvention: matches the Standard Schema spec exactly
17
+ export namespace StandardSchemaV1 {
18
+ export interface Props<Input = unknown, Output = Input> {
19
+ readonly version: 1
20
+ readonly vendor: string
21
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>
22
+ readonly types?: Types<Input, Output> | undefined
23
+ }
24
+
25
+ export type Result<Output> = SuccessResult<Output> | FailureResult
26
+
27
+ export interface SuccessResult<Output> {
28
+ readonly value: Output
29
+ readonly issues?: undefined
30
+ }
31
+
32
+ export interface FailureResult {
33
+ readonly issues: ReadonlyArray<Issue>
34
+ }
35
+
36
+ export interface Issue {
37
+ readonly message: string
38
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined
39
+ }
40
+
41
+ export interface PathSegment {
42
+ readonly key: PropertyKey
43
+ }
44
+
45
+ export interface Types<Input = unknown, Output = Input> {
46
+ readonly input: Input
47
+ readonly output: Output
48
+ }
49
+
50
+ export type InferInput<Schema extends StandardSchemaV1> = NonNullable<
51
+ Schema['~standard']['types']
52
+ >['input']
53
+
54
+ export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<
55
+ Schema['~standard']['types']
56
+ >['output']
57
+ }
@@ -0,0 +1,10 @@
1
+ import type { CacheSnapshotEntry } from './CacheSnapshotEntry.ts'
2
+
3
+ /*
4
+ Payload of one streamed `window.__belteResolve(...)` call. A full
5
+ `CacheSnapshotEntry` settles the placeholder with warm data; a `{ key, miss }`
6
+ marker means the server couldn't snapshot that body (binary, rejected, evicted)
7
+ so the client settles the placeholder with a live re-fetch instead. Discriminate
8
+ on the `miss` field.
9
+ */
10
+ export type StreamedResolution = CacheSnapshotEntry | { key: string; miss: true }
@@ -0,0 +1,13 @@
1
+ /*
2
+ Wire descriptor for a {#await} cache read that's still pending at first flush.
3
+ Shipped in `__SSR__.streaming` so the client can pre-create a deferred cache
4
+ entry for the key before hydration — `cache()` then hits that placeholder
5
+ instead of firing its own fetch, and the streamed `__belteResolve` settles it.
6
+ `url`/`method` reconstruct the entry's Request for the rare miss fallback (a
7
+ non-snapshottable body the client re-fetches live).
8
+ */
9
+ export type StreamingPlaceholder = {
10
+ key: string
11
+ url: string
12
+ method: string
13
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ The thing `subscribe()` reads from: an AsyncIterable carrying a stable
3
+ `name` used as the subscription registry key. Both `Socket<T>` (the
4
+ declared broadcast primitive) and the result of `fn.stream(args)`
5
+ (per-call HTTP stream consumer) satisfy this shape, so subscribe() can
6
+ share one iterator across multiple readers regardless of source.
7
+
8
+ The name on a Socket comes from the file path under `src/server/sockets/`.
9
+ The name on an fn.stream(args) result is `keyForRemoteCall(method, url,
10
+ args)` — the same key cache() uses — so two subscribers to the same
11
+ remote-call args dedupe to one underlying fetch.
12
+ */
13
+ export interface Subscribable<T> extends AsyncIterable<T> {
14
+ readonly name: string
15
+ }
@@ -0,0 +1,5 @@
1
+ import type { CompileOptions } from 'svelte/compiler'
2
+
3
+ export type SvelteConfig = {
4
+ compilerOptions?: Partial<CompileOptions>
5
+ }
@@ -0,0 +1,20 @@
1
+ import type { StandardSchemaV1 } from './types/StandardSchemaV1.ts'
2
+
3
+ /*
4
+ Attaches a `toJSONSchema()` projection to a Standard Schema whose library
5
+ doesn't expose one natively. jsonSchemaForSchema probes that method to feed the
6
+ OpenAPI document, the MCP tool schemas, the CLI flag help, and the bundle setup
7
+ form. Zod 4 / Effect / Arktype carry their own; everything else wraps once where
8
+ the schema is declared:
9
+
10
+ export const config = env(withJsonSchema(vSchema, (s) => toJsonSchema(s)))
11
+
12
+ Mutates and returns the same schema with the method attached, so the wrapped
13
+ value stays usable everywhere the bare schema was.
14
+ */
15
+ export function withJsonSchema<Schema extends StandardSchemaV1>(
16
+ schema: Schema,
17
+ toJsonSchema: (schema: Schema) => Record<string, unknown>,
18
+ ): Schema & { toJSONSchema: () => Record<string, unknown> } {
19
+ return Object.assign(schema, { toJSONSchema: () => toJsonSchema(schema) })
20
+ }
@@ -0,0 +1,13 @@
1
+ import { mkdir } from 'node:fs/promises'
2
+ import { appDataDir } from './appDataDir.ts'
3
+ import { lastConnectionPath } from './lastConnectionPath.ts'
4
+ import type { LastConnection } from './types/LastConnection.ts'
5
+
6
+ // Persists the connection intent, creating the data dir on first write.
7
+ export async function writeLastConnection(
8
+ programName: string,
9
+ value: LastConnection,
10
+ ): Promise<void> {
11
+ await mkdir(appDataDir(programName), { recursive: true })
12
+ await Bun.write(lastConnectionPath(programName), JSON.stringify(value))
13
+ }
@@ -0,0 +1,67 @@
1
+ import { pageUrlForFile } from './pageUrlForFile.ts'
2
+ import { parseRouteSegments } from './parseRouteSegments.ts'
3
+
4
+ /*
5
+ Walks a `[name]` / `[...rest]` route URL and returns the param shape it
6
+ declares. Catch-all segments map to `string` under their declared name —
7
+ the server's toBunRoutePattern renames Bun's `*` key back to that name
8
+ when dispatching, so the page component sees `params.rest`, not
9
+ `params['*']`.
10
+ */
11
+ function paramsForRoute(routeUrl: string): Record<string, 'string'> {
12
+ return Object.fromEntries(
13
+ parseRouteSegments(routeUrl)
14
+ .filter((segment) => segment.kind === 'param')
15
+ .map((segment) => [segment.name, 'string'] as const),
16
+ )
17
+ }
18
+
19
+ function renderParamsShape(shape: Record<string, 'string'>): string {
20
+ const keys = Object.keys(shape)
21
+ if (keys.length === 0) {
22
+ return 'Record<string, never>'
23
+ }
24
+ return `{ ${keys.map((key) => `${JSON.stringify(key)}: string`).join('; ')} }`
25
+ }
26
+
27
+ /*
28
+ Emits a `.d.ts` that augments belte's `Routes` interface with one entry per
29
+ page file in the project. Page picks this up as a discriminated union keyed
30
+ on `route`, so `if (page.route === '/media/[id]') page.params.id` is typed
31
+ automatically without consumers writing route types by hand.
32
+ The file is written to `src/.belte/routes.d.ts` so the consumer's existing
33
+ src tsconfig include picks it up with no extra configuration. The augmented
34
+ module is keyed on the name the project imports belte under (`importName`),
35
+ so the augmentation matches the consumer's `page` import whether belte is
36
+ installed directly (`@belte/belte`) or behind an alias.
37
+ */
38
+ export async function writeRoutesDts({
39
+ cwd,
40
+ pageFiles,
41
+ importName,
42
+ }: {
43
+ cwd: string
44
+ pageFiles: string[]
45
+ importName: string
46
+ }): Promise<void> {
47
+ const entries = pageFiles
48
+ .map((file) => ({
49
+ route: pageUrlForFile(file),
50
+ params: paramsForRoute(pageUrlForFile(file)),
51
+ }))
52
+ .toSorted((a, b) => a.route.localeCompare(b.route))
53
+ .map(
54
+ ({ route, params }) => ` ${JSON.stringify(route)}: ${renderParamsShape(params)}`,
55
+ )
56
+ .join('\n')
57
+ const contents = `// Generated by belte. Do not edit by hand.
58
+ declare module '${importName}/browser/page' {
59
+ interface Routes {
60
+ ${entries}
61
+ }
62
+ }
63
+
64
+ export {}
65
+ `
66
+ await Bun.write(`${cwd}/src/.belte/routes.d.ts`, contents)
67
+ }
@@ -0,0 +1,11 @@
1
+ import { verbRegistry } from '../server/rpc/verbRegistry.ts'
2
+
3
+ /*
4
+ Empties the process-wide verb registry. defineVerb registers on construction
5
+ and never removes, so verbs declared in one test stay discoverable by name in
6
+ the next. Call in beforeEach to isolate a suite that defines verbs inline,
7
+ keeping createTestClient's name lookup unambiguous across tests.
8
+ */
9
+ export function clearVerbRegistry(): void {
10
+ verbRegistry.clear()
11
+ }
@@ -0,0 +1,78 @@
1
+ import type { AppModule } from '../server/AppModule.ts'
2
+ import { dispatchVerbInProcess } from '../server/rpc/dispatchVerbInProcess.ts'
3
+ import { findVerbByCommandName } from '../server/rpc/findVerbByCommandName.ts'
4
+ import type { VerbRegistryEntry } from '../server/rpc/types/VerbRegistryEntry.ts'
5
+ import { decodeResponse } from '../shared/decodeResponse.ts'
6
+
7
+ /*
8
+ Each property is a callable: invoking it decodes the body (and throws
9
+ HttpError on non-2xx, like a real remote call), while `.raw(args)` returns
10
+ the underlying Response untouched for status/header/streaming assertions.
11
+ */
12
+ type TestInvoker = ((args?: unknown) => Promise<unknown>) & {
13
+ raw: (args?: unknown) => Promise<Response>
14
+ }
15
+
16
+ type AnyApi = Record<string, TestInvoker>
17
+
18
+ /*
19
+ In-process client for tests. Like createClient's in-process mode it discovers
20
+ verbs from the registry (populated by the test's defineVerb calls) and routes
21
+ through dispatchVerbInProcess — same synthesize-and-fetch the CLI and MCP
22
+ surfaces use, so they can't drift on how a verb is invoked. Each call runs
23
+ inside runWithRequestScope, the same seam createServer crosses for a live
24
+ request, so request-scoped helpers behave identically to production — a fresh
25
+ per-request cache(), the cookie jar with Set-Cookie flush, request()/server()
26
+ resolution, and handleError/500 fallback on a throw.
27
+
28
+ `headers` pre-populates the synthetic Request (auth, cookies) for handlers that
29
+ read inbound identity; `app.handleError` lets a suite assert its custom error
30
+ response. No `url` — this never hits the network, so it needs the rpc modules
31
+ imported into the process, not a running server.
32
+ */
33
+ export function createTestClient<Api extends AnyApi = AnyApi>(opts?: {
34
+ baseUrl?: string
35
+ headers?: HeadersInit
36
+ app?: AppModule
37
+ }): Api {
38
+ const baseUrl = opts?.baseUrl ?? 'http://localhost/'
39
+
40
+ /*
41
+ Fresh Headers per call: buildRpcRequest mutates it (sets content-type on
42
+ body verbs), so a shared instance would leak that mutation across calls.
43
+ */
44
+ function send(entry: VerbRegistryEntry, args: unknown): Promise<Response> {
45
+ return dispatchVerbInProcess({
46
+ entry,
47
+ args,
48
+ baseUrl,
49
+ headers: new Headers(opts?.headers),
50
+ app: opts?.app,
51
+ })
52
+ }
53
+
54
+ function buildInvoker(entry: VerbRegistryEntry): TestInvoker {
55
+ const invoker = (async (args?: unknown) =>
56
+ decodeResponse(await send(entry, args))) as TestInvoker
57
+ invoker.raw = (args?: unknown) => send(entry, args)
58
+ return invoker
59
+ }
60
+
61
+ // Memoise per-name so repeated accesses skip the registry scan + closure alloc.
62
+ const invokerCache = new Map<string, TestInvoker | undefined>()
63
+
64
+ return new Proxy({} as Api, {
65
+ get(_target, prop): TestInvoker | undefined {
66
+ if (typeof prop !== 'string') {
67
+ return undefined
68
+ }
69
+ if (invokerCache.has(prop)) {
70
+ return invokerCache.get(prop)
71
+ }
72
+ const entry = findVerbByCommandName(prop)
73
+ const invoker = entry ? buildInvoker(entry) : undefined
74
+ invokerCache.set(prop, invoker)
75
+ return invoker
76
+ },
77
+ })
78
+ }
package/src/preload.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { plugin } from 'bun'
2
+ import { belteResolverPlugin } from './belteResolverPlugin.ts'
3
+ import { loadSvelteConfig } from './lib/shared/loadSvelteConfig.ts'
4
+ import { sveltePlugin } from './sveltePlugin.ts'
5
+
6
+ const mode = (process.env.BELTE_SVELTE_MODE ?? 'server') as 'server' | 'client'
7
+ const svelteConfig = await loadSvelteConfig()
8
+
9
+ await plugin(sveltePlugin({ generate: mode, svelteConfig }))
10
+ await plugin(belteResolverPlugin({ target: mode }))
11
+
12
+ await plugin({
13
+ name: 'css-noop',
14
+ setup(build) {
15
+ build.onLoad({ filter: /\.css$/ }, () => ({
16
+ contents: 'export default {};',
17
+ loader: 'js',
18
+ }))
19
+ },
20
+ })
@@ -0,0 +1,92 @@
1
+ import { Glob } from 'bun'
2
+ import { log } from './lib/shared/log.ts'
3
+
4
+ const TEMPLATE_DIR = new URL('../template', import.meta.url).pathname
5
+
6
+ /*
7
+ Copies the bundled template directory into `${cwd}/${name}`. Refuses to write
8
+ into a non-empty directory so an accidental run doesn't overwrite real work.
9
+ */
10
+ export async function scaffold({
11
+ cwd = process.cwd(),
12
+ name,
13
+ }: {
14
+ cwd?: string
15
+ name: string
16
+ }): Promise<string> {
17
+ const trimmed = name.trim()
18
+ if (trimmed === '') {
19
+ throw new Error('[belte] project name is required: bunx belte scaffold <name>')
20
+ }
21
+ const target = resolveTarget(cwd, trimmed)
22
+ if (await targetIsNonEmpty(target)) {
23
+ throw new Error(`[belte] target directory is not empty: ${target}`)
24
+ }
25
+ if (!(await Bun.file(`${TEMPLATE_DIR}/package.json`).exists())) {
26
+ throw new Error(`[belte] template missing at ${TEMPLATE_DIR}`)
27
+ }
28
+ await copyTree(TEMPLATE_DIR, target)
29
+ log.success(`scaffolded belte project at ${target}`)
30
+ log.detail(' next steps:')
31
+ if (target !== cwd) {
32
+ log.detail(` cd ${trimmed}`)
33
+ }
34
+ log.detail(' bun install')
35
+ log.detail(' bun run dev')
36
+ return target
37
+ }
38
+
39
+ /*
40
+ Copies every file under `from` into `to`, preserving relative paths. Uses
41
+ Bun.Glob to enumerate (dotfiles included) and Bun.write to materialize each
42
+ file — Bun.write auto-creates parent directories.
43
+ */
44
+ async function copyTree(from: string, to: string): Promise<void> {
45
+ const files = await Array.fromAsync(
46
+ new Glob('**/*').scan({ cwd: from, onlyFiles: true, dot: true }),
47
+ )
48
+ await Promise.all(
49
+ files.map(async (relativePath) => {
50
+ const source = Bun.file(`${from}/${relativePath}`)
51
+ await Bun.write(`${to}/${relativePath}`, source)
52
+ }),
53
+ )
54
+ }
55
+
56
+ /*
57
+ Resolves the user-supplied name against the working directory. Absolute
58
+ paths (`/tmp/foo`) and `~`-prefixed paths are used as-is; relative names
59
+ are joined onto `cwd`.
60
+ */
61
+ function resolveTarget(cwd: string, name: string): string {
62
+ if (name === '.' || name === './') {
63
+ return cwd
64
+ }
65
+ if (name.startsWith('/')) {
66
+ return name
67
+ }
68
+ if (name.startsWith('~/')) {
69
+ const home = process.env.HOME ?? ''
70
+ return `${home}${name.slice(1)}`
71
+ }
72
+ return `${cwd}/${name}`
73
+ }
74
+
75
+ /*
76
+ True when the target exists and contains at least one entry. Uses Bun.Glob
77
+ rather than fs.readdir to honor the project's "Bun-first" rule. A missing
78
+ directory is reported as empty so first-time scaffolds proceed.
79
+ */
80
+ async function targetIsNonEmpty(target: string): Promise<boolean> {
81
+ try {
82
+ for await (const _ of new Glob('*').scan({ cwd: target, onlyFiles: false, dot: true })) {
83
+ return true
84
+ }
85
+ } catch (error) {
86
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
87
+ return false
88
+ }
89
+ throw error
90
+ }
91
+ return false
92
+ }
@@ -0,0 +1,25 @@
1
+ import type { BunPlugin } from 'bun'
2
+ import { belteResolverPlugin } from './belteResolverPlugin.ts'
3
+ import type { SvelteConfig } from './lib/shared/types/SvelteConfig.ts'
4
+ import { sveltePlugin } from './sveltePlugin.ts'
5
+
6
+ /*
7
+ The server-target Bun.build plugin pair shared by compile / buildCli /
8
+ bundleApp: the svelte loader (server generate) plus belte's virtual-module
9
+ resolver. `embedAssets` flips on the zstd asset embed used by the standalone
10
+ server binary; the CLI + launcher builds leave it off.
11
+ */
12
+ export function serverBuildPlugins({
13
+ cwd,
14
+ svelteConfig,
15
+ embedAssets = false,
16
+ }: {
17
+ cwd: string
18
+ svelteConfig?: SvelteConfig
19
+ embedAssets?: boolean
20
+ }): BunPlugin[] {
21
+ return [
22
+ sveltePlugin({ generate: 'server', svelteConfig }),
23
+ belteResolverPlugin({ cwd, embedAssets, target: 'server' }),
24
+ ]
25
+ }