@aventara/build 1.0.0-rc.13 → 1.0.0-rc.14

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @aventara/build
2
2
 
3
+ ## 1.0.0-rc.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 0895a93: `avDehydrate` and `avHydrate` are typed: data handed from a Server Component to a Client Component as props keeps its type, with no cast.
8
+
9
+ - `avDehydrate(data)` (`@aventara/next`) returns an `AvDehydrated<T>` for data of type `T`, and `avHydrate(value)` (`@/aventara/client`) of an `AvDehydrated<T>` returns the `T`, its `Date`, `bigint`, `Uint8Array` and `AvDecimal` values included. Type an SWR `fallback` prop `AvDehydrated<T>` and pass `avHydrate(fallback)` to `SWRConfig` as it is.
10
+ - `AvDehydrated<T>` is new, exported by `@aventara/next` and by the `src/aventara/client.ts` that `aventara-build --client` writes; the two are one type. It is opaque: a plain object, the data itself, or the dehydrated form of another type is a compile error where an `AvDehydrated<T>` is expected.
11
+ - A Resource or enum named `AvDehydrated` or `avHydrate` is now emitted under a renamed identifier (`AvDehydratedModel`, `avHydrateModel`), with a warning, as other names the generated client owns are. Before, `src/aventara/client.ts`'s own declaration hid a Resource type of that name, which could not be imported from it.
12
+ - Read data you dehydrate through `@/aventara/universal`: `@/aventara/server` types a decimal as core's `AvDecimal`, while `avHydrate` revives it as the browser client's.
13
+ - Pass `avHydrate(fallback)` to `SWRConfig`, never the dehydrated value itself: SWR's `fallback` is typed `any`, so the compiler cannot catch it.
14
+ - `avHydrate` still takes `unknown` and returns `unknown`; `avDehydrate` of an `unknown` value returns an `AvDehydrated<unknown>`. `serializeData: avDehydrate` and `deserializeData: avHydrate` in TanStack Query are written as before.
15
+ - The agent skills show the SWR props pattern typed, with no cast. The frontend skill's refresh line no longer names `npx`, and says a file you edited is kept with a warning naming it, and replaced with `--force`.
16
+
17
+ - Updated dependencies [1c5eaa3]
18
+ - Updated dependencies [0895a93]
19
+ - @aventara/core@1.0.0-rc.14
20
+ - @aventara/client@1.0.0-rc.14
21
+
3
22
  ## 1.0.0-rc.13
4
23
 
5
24
  ### Minor Changes
package/README.md CHANGED
@@ -135,7 +135,7 @@ so no running server is needed:
135
135
 
136
136
  | File | What it holds |
137
137
  |---|---|
138
- | `src/aventara/client.ts` | `avClient`, the typed client calling the app's own `api` (`/api`) from the browser, and `avHydrate`; and every name `avclient generate`'s `AvClient.ts` exports besides its default: `AvClient`, the Resource types, the enums, `AvDecimal` and the error classes |
138
+ | `src/aventara/client.ts` | `avClient`, the typed client calling the app's own `api` (`/api`) from the browser, `avHydrate` and its `AvDehydrated<T>` type; and every name `avclient generate`'s `AvClient.ts` exports besides its default: `AvClient`, the Resource types, the enums, `AvDecimal` and the error classes |
139
139
  | `src/aventara/universal.ts` | `avClient` for both sides: in the browser it calls the app's own `api`, on the server it calls the app in process, through what `ready()` from `@aventara/next` registers in `src/instrumentation.ts`, with that request's state |
140
140
  | `src/aventara/generated/` (the client's modules) | the same modules `avclient generate` writes for the same ClientContract, but with the app's own `api` as the entrypoint, and saying to regenerate them with `aventara-build --client` |
141
141
 
@@ -152,7 +152,7 @@ function optionsImport(options) {
152
152
  }
153
153
  function entrySource(style, accessVerbs, options) {
154
154
  const from = (module) => JSON.stringify(importSpecifier(module, style));
155
- const { tagKey, valueKey, objectTag, scalarTags } = HYDRATION_FORMAT;
155
+ const { tagKey, valueKey, objectTag, scalarTags, typeKey } = HYDRATION_FORMAT;
156
156
  const tagged = [...scalarTags, objectTag]
157
157
  .map((tag) => JSON.stringify(tag))
158
158
  .join(" | ");
@@ -221,17 +221,35 @@ function revivedMembers(record: Readonly<Record<string, unknown>>): Record<strin
221
221
  return Object.fromEntries(Object.entries(record).map(([key, member]) => [key, avHydrate(member)]));
222
222
  }
223
223
 
224
+ /**
225
+ * Data of type \`T\` as \`avDehydrate\` (from \`@aventara/next\`) sends it from the
226
+ * server: opaque, read back as the \`T\` by \`avHydrate\`. Type a Client
227
+ * Component's prop with it to take server data with no cast. It is
228
+ * \`@aventara/next\`'s \`AvDehydrated\`, declared here again: its one member is a
229
+ * brand of the type only, never of the value.
230
+ */
231
+ export type AvDehydrated<T> = {
232
+ /** The type the value was dehydrated from: the type's brand, no member of the value. */
233
+ readonly ${JSON.stringify(typeKey)}: T;
234
+ };
235
+
224
236
  /**
225
237
  * Revives data that \`avDehydrate\` (from \`@aventara/next\`) made safe to pass
226
238
  * from the server to the browser: each tagged Date, bigint, Uint8Array and
227
239
  * decimal becomes the value this client reads, a decimal this client's own
228
240
  * AvDecimal.
229
241
  * Arrays and plain objects are copied with their members revived; any other
230
- * value is returned as it is. Give it to TanStack Query as \`deserializeData\`,
231
- * or call it on an SWR \`fallback\`.
242
+ * value is returned as it is. An \`AvDehydrated<T>\` revives as the \`T\`: call it
243
+ * on a prop of that type, such as an SWR \`fallback\`, and pass on what it
244
+ * returns, never the dehydrated value itself (SWR's \`fallback\` is typed
245
+ * \`any\`, so the type cannot catch it). Give it to TanStack Query as
246
+ * \`deserializeData\`.
232
247
  *
233
248
  * @throws TypeError when a tagged value is not one avDehydrate writes.
234
249
  */
250
+ export function avHydrate<T>(dehydrated: AvDehydrated<T>): T;
251
+ /** For a caller that cannot name the data's type: TanStack Query's \`deserializeData\`. */
252
+ export function avHydrate(dehydrated: unknown): unknown;
235
253
  export function avHydrate(dehydrated: unknown): unknown {
236
254
  if (Array.isArray(dehydrated)) {
237
255
  return dehydrated.map((member: unknown) => avHydrate(member));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aventara/build",
3
- "version": "1.0.0-rc.13",
3
+ "version": "1.0.0-rc.14",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "Compiles an Aventara application's Contracts at build time, for serverless and edge cold starts.",
6
6
  "type": "module",
@@ -16,18 +16,18 @@
16
16
  "CHANGELOG.md"
17
17
  ],
18
18
  "dependencies": {
19
- "@aventara/client": "1.0.0-rc.13",
19
+ "@aventara/client": "1.0.0-rc.14",
20
20
  "jiti": "2.7.0"
21
21
  },
22
22
  "peerDependencies": {
23
- "@aventara/core": "1.0.0-rc.13",
23
+ "@aventara/core": "1.0.0-rc.14",
24
24
  "typescript": ">=5.7.0 <7"
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public"
28
28
  },
29
29
  "devDependencies": {
30
- "@aventara/core": "1.0.0-rc.13",
30
+ "@aventara/core": "1.0.0-rc.14",
31
31
  "@types/node": "24.10.1",
32
32
  "typescript": "^5.9.2"
33
33
  },