@bakery-framework/plugin-vue 2.0.0-rc.1 → 2.0.0-rc.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bakery-framework/plugin-vue",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.2",
4
4
  "description": "Bakery vue plugin.",
5
5
  "keywords": [
6
6
  "bakery",
@@ -43,7 +43,7 @@
43
43
  "vue": "^3.5.38"
44
44
  },
45
45
  "dependencies": {
46
- "@bakery-framework/core": "^2.0.0-rc.1"
46
+ "@bakery-framework/core": "^2.0.0-rc.2"
47
47
  },
48
48
  "engines": {
49
49
  "bun": ">=1.4.0"
package/src/index.ts CHANGED
@@ -12,6 +12,17 @@ import { rewriteVueImports } from './utils'
12
12
  */
13
13
  export type { CustomElementsOption, VuePluginOptions } from './types'
14
14
 
15
+ /**
16
+ * The request body inside a `<script server>` block, and anything it calls.
17
+ *
18
+ * Pairs with `getRequest()` from `@bakery-framework/core`. Both replace the
19
+ * `req` and `body` globals this plugin declared in `vue.d.ts`, which only
20
+ * reached a file when that `.d.ts` happened to land in the tsconfig project
21
+ * an editor resolved for it. The globals still work; they are no longer the
22
+ * only way, and they are no longer load-bearing.
23
+ */
24
+ export { getBody } from './server-context'
25
+
15
26
  export default function vuePlugin(options?: VuePluginOptions) {
16
27
  if (options) setVuePluginOptions(options)
17
28
  return definePlugin({
@@ -0,0 +1,37 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks'
2
+
3
+ /**
4
+ * The parsed body of the request a `<script server>` block is running for.
5
+ *
6
+ * Separate from core's `getRequest()` deliberately: the request is core's and
7
+ * every surface has one, while `body` is this plugin's own computation
8
+ * (`VueHandler.params(req, finalParams)`, which merges route params with the
9
+ * parsed payload). A `.tsx` page receives its body as a function argument and
10
+ * has no use for this.
11
+ *
12
+ * Why it exists at all is the same reason as `getRequest()`. The block used
13
+ * to reach `body` as a global declared in `vue.d.ts`, which only works if
14
+ * that `.d.ts` lands in whatever tsconfig project an editor resolves for the
15
+ * SFC, and for an SFC it routinely does not. An import cannot fail that way,
16
+ * it carries a real type instead of `any`, and it reaches a helper the block
17
+ * calls rather than stopping at the wrapper's parameter list.
18
+ */
19
+ const bodyStore = new AsyncLocalStorage<{ body: unknown }>()
20
+
21
+ /** Run `fn` with `body` visible to `getBody()`. Called by the plugin only. */
22
+ export function runWithServerBody<T>(body: unknown, fn: () => T): T {
23
+ return bodyStore.run({ body }, fn)
24
+ }
25
+
26
+ /**
27
+ * The request body, inside a `<script server>` block or anything it calls.
28
+ *
29
+ * Unlike {@link import('@bakery-framework/core').getRequest} this does **not**
30
+ * throw when absent: a GET with no payload and no route params is an ordinary
31
+ * request, and `undefined` is the honest answer rather than an error
32
+ * condition. The type parameter is the caller's assertion about a shape the
33
+ * framework cannot know, exactly as it was when this was an `any` global.
34
+ */
35
+ export function getBody<T = unknown>(): T | undefined {
36
+ return bodyStore.getStore()?.body as T | undefined
37
+ }
package/src/utils.ts CHANGED
@@ -7,6 +7,7 @@ import { LRUCache } from '@bakery-framework/core/cache/lru'
7
7
  import { Bakery } from '@bakery-framework/core/core/bakery'
8
8
  import { Logger } from '@bakery-framework/core/logger'
9
9
  import { fs, is, Try } from '@bakery-framework/core/utils'
10
+ import { runWithServerBody } from './server-context'
10
11
  import type { ParsedCacheEntry, ServerResponseOptions, VueMeta } from './types'
11
12
 
12
13
  const logger = new Logger('vue')
@@ -524,7 +525,11 @@ export async function getServerResponse(options: ServerResponseOptions) {
524
525
  })
525
526
  const execPromise = Promise.resolve(
526
527
  is.function(exported)
527
- ? exported(req, body, actionName, actionArgs)
528
+ ? // The parameters stay, so every existing block keeps working; the
529
+ // store is what lets `getBody()` reach a helper the block calls.
530
+ runWithServerBody(body, () =>
531
+ exported(req, body, actionName, actionArgs),
532
+ )
528
533
  : exported,
529
534
  )
530
535
  const params = await Promise.race([execPromise, timeoutPromise])