@nkzw/fate 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -552,18 +552,9 @@ const PostView = view<Post>()({
552
552
  Now you can apply the `useListView` hook inside of your `PostCard` component to read the list of comments and load more comments when needed:
553
553
 
554
554
  ```tsx
555
- export function PostCard({
556
- detail,
557
- post: postRef,
558
- }: {
559
- detail?: boolean;
560
- post: ViewRef<'Post'>;
561
- }) {
555
+ export function PostCard({ detail, post: postRef }: { detail?: boolean; post: ViewRef<'Post'> }) {
562
556
  const post = useView(PostView, postRef);
563
- const [comments, loadNext] = useListView(
564
- CommentConnectionView,
565
- post.comments,
566
- );
557
+ const [comments, loadNext] = useListView(CommentConnectionView, post.comments);
567
558
 
568
559
  return (
569
560
  <div>
@@ -615,10 +606,7 @@ If you are not using an async component library, you can use React's `useTransit
615
606
  const LikeButton = ({ post }: { post: { id: string; likes: number } }) => {
616
607
  const fate = useFateClient();
617
608
  const [, startTransition] = useTransition();
618
- const [result, like, isPending] = useActionState(
619
- fate.actions.post.like,
620
- null,
621
- );
609
+ const [result, like, isPending] = useActionState(fate.actions.post.like, null);
622
610
 
623
611
  return (
624
612
  <button
@@ -805,10 +793,7 @@ const [result, like] = useActionState(fate.actions.post.like, null);
805
793
  useEffect(() => {
806
794
  if (result?.error) {
807
795
  // Reset the action state after 3 seconds.
808
- const timeout = setTimeout(
809
- () => startTransition(() => like('reset')),
810
- 3000,
811
- );
796
+ const timeout = setTimeout(() => startTransition(() => like('reset')), 3000);
812
797
  return () => clearTimeout(timeout);
813
798
  }
814
799
  }, [like, result]);
package/lib/cli.mjs CHANGED
@@ -130,22 +130,22 @@ const generate = async () => {
130
130
  });
131
131
  continue;
132
132
  }
133
- for (const [queryName, root$1] of routerRoots) {
134
- if (root$1.kind !== "query") continue;
135
- if (procedureName === root$1.procedure && type === "query") queryEntries.push({
133
+ for (const [queryName, root] of routerRoots) {
134
+ if (root.kind !== "query") continue;
135
+ if (procedureName === root.procedure && type === "query") queryEntries.push({
136
136
  name: queryName,
137
- procedure: root$1.procedure,
137
+ procedure: root.procedure,
138
138
  router,
139
- type: root$1.type
139
+ type: root.type
140
140
  });
141
141
  }
142
- for (const [listName, root$1] of routerRoots) {
143
- if (root$1.kind !== "list") continue;
144
- if (procedureName === root$1.procedure && type === "query") listEntries.push({
142
+ for (const [listName, root] of routerRoots) {
143
+ if (root.kind !== "list") continue;
144
+ if (procedureName === root.procedure && type === "query") listEntries.push({
145
145
  list: listName,
146
- procedure: root$1.procedure,
146
+ procedure: root.procedure,
147
147
  router,
148
- type: root$1.type
148
+ type: root.type
149
149
  });
150
150
  }
151
151
  }
@@ -203,7 +203,7 @@ const generate = async () => {
203
203
  const source = `// @generated by \`pnpm fate generate\`
204
204
  ${typeImports}
205
205
  import { createTRPCProxyClient } from '@trpc/client';
206
- import { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
206
+ import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
207
207
  import { clientRoot, createClient, createTRPCTransport, mutation } from 'react-fate';
208
208
 
209
209
  type TRPCClientType = ReturnType<typeof createTRPCProxyClient<AppRouter>>;
package/lib/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
- import { A as ViewSelection, B as RequestOptions, C as TypeConfig, D as ViewEntity, E as ViewData, F as isViewTag, H as Transport, I as FateMutations, L as mutation, M as ViewTag, N as __FateEntityBrand, O as ViewEntityName, P as __FateSelectionBrand, R as FateClient, S as Snapshot, T as View, U as createTRPCTransport, V as createClient, W as getSelectionPlan, _ as Pagination, a as Entity, b as RootDefinition, c as FateThenable, d as MutationDefinition, f as MutationEntity, g as NodesItem, h as MutationResult, i as ConnectionTag, j as ViewSnapshot, k as ViewRef, l as ListItem, m as MutationInput, n as ConnectionMetadata, o as EntityId, p as MutationIdentifier, r as ConnectionRef, s as FateRoots, t as AnyRecord, u as Mask, v as Request, w as TypeName, x as Selection, y as RequestResult, z as RequestMode } from "./types-BiDLhb07.mjs";
1
+ import { A as ViewSelection, B as RequestOptions, C as TypeConfig, D as ViewEntity, E as ViewData, F as isViewTag, G as getSelectionPlan, H as Transport, I as FateMutations, L as mutation, M as ViewTag, N as __FateEntityBrand, O as ViewEntityName, P as __FateSelectionBrand, R as FateClient, S as Snapshot, T as View, U as createTRPCTransport, V as createClient, _ as Pagination, a as Entity, b as RootDefinition, c as FateThenable, d as MutationDefinition, f as MutationEntity, g as NodesItem, h as MutationResult, i as ConnectionTag, j as ViewSnapshot, k as ViewRef, l as ListItem, m as MutationInput, n as ConnectionMetadata, o as EntityId, p as MutationIdentifier, r as ConnectionRef, s as FateRoots, t as AnyRecord, u as Mask, v as Request, w as TypeName, x as Selection, y as RequestResult, z as RequestMode } from "./types-HECWvGpd.mjs";
2
2
 
3
3
  //#region src/root.d.ts
4
-
5
4
  /**
6
5
  * Defines a root query for an entity type, capturing the response shape.
7
6
  */
package/lib/index.mjs CHANGED
@@ -264,7 +264,7 @@ function intersects(a, b) {
264
264
  }
265
265
 
266
266
  //#endregion
267
- //#region ../../node_modules/.pnpm/@trpc+server@11.7.2_typescript@5.9.3/node_modules/@trpc/server/dist/getErrorShape-BH60iMC2.mjs
267
+ //#region ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/getErrorShape-vC8mUXJD.mjs
268
268
  var __create = Object.create;
269
269
  var __defProp = Object.defineProperty;
270
270
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -432,17 +432,17 @@ const MutationKind = "__fate__mutation";
432
432
  /**
433
433
  * Collects all view payloads that apply to the given ref.
434
434
  */
435
- const getViewPayloads = (view$1, ref) => {
435
+ const getViewPayloads = (view, ref) => {
436
436
  const result = [];
437
- for (const [key, value] of Object.entries(view$1)) if (isViewTag(key) && (!ref || ref[ViewsTag]?.has(key))) result.push(value);
437
+ for (const [key, value] of Object.entries(view)) if (isViewTag(key) && (!ref || ref[ViewsTag]?.has(key))) result.push(value);
438
438
  return result;
439
439
  };
440
440
  /**
441
441
  * Returns the set of view tags defined on a view composition.
442
442
  */
443
- const getViewNames = (view$1) => {
443
+ const getViewNames = (view) => {
444
444
  const result = /* @__PURE__ */ new Set();
445
- for (const key of Object.keys(view$1)) if (isViewTag(key)) result.add(key);
445
+ for (const key of Object.keys(view)) if (isViewTag(key)) result.add(key);
446
446
  return result;
447
447
  };
448
448
  /**
package/lib/server.d.mts CHANGED
@@ -1,6 +1,5 @@
1
- import { t as AnyRecord } from "./types-BiDLhb07.mjs";
1
+ import { W as QueryProcedure, t as AnyRecord } from "./types-HECWvGpd.mjs";
2
2
  import { z } from "zod";
3
- import { TRPCProcedureBuilder } from "@trpc/server";
4
3
 
5
4
  //#region src/server/dataView.d.ts
6
5
  declare const dataViewFieldsKey: unique symbol;
@@ -11,18 +10,18 @@ type ResolverSelect<Context> = AnyRecord | ((options: {
11
10
  type Bivariant<Fn extends (...args: Array<any>) => unknown> = {
12
11
  bivariance(...args: Parameters<Fn>): ReturnType<Fn>;
13
12
  }['bivariance'];
14
- type ResolverResolve<Item$1 extends AnyRecord, Result, Context> = Bivariant<(item: Item$1, context?: Context, args?: AnyRecord) => Promise<Result> | Result>;
15
- type ResolverAuthorize<Item$1 extends AnyRecord, Context> = Bivariant<(item: Item$1, context?: Context, args?: AnyRecord) => Promise<boolean> | boolean>;
13
+ type ResolverResolve<Item extends AnyRecord, Result, Context> = Bivariant<(item: Item, context?: Context, args?: AnyRecord) => Promise<Result> | Result>;
14
+ type ResolverAuthorize<Item extends AnyRecord, Context> = Bivariant<(item: Item, context?: Context, args?: AnyRecord) => Promise<boolean> | boolean>;
16
15
  /**
17
16
  * Field configuration for selecting and resolving a computed value on the backend.
18
17
  */
19
- type ResolverField<Item$1 extends AnyRecord, Result, Context> = {
20
- authorize?: ResolverAuthorize<Item$1, Context>;
18
+ type ResolverField<Item extends AnyRecord, Result, Context> = {
19
+ authorize?: ResolverAuthorize<Item, Context>;
21
20
  kind: 'resolver';
22
- resolve: ResolverResolve<Item$1, Result, Context>;
21
+ resolve: ResolverResolve<Item, Result, Context>;
23
22
  select?: ResolverSelect<Context>;
24
23
  };
25
- type DataField<Item$1 extends AnyRecord> = true | DataView<AnyRecord> | ResolverField<Item$1, any, any>;
24
+ type DataField<Item extends AnyRecord> = true | DataView<AnyRecord> | ResolverField<Item, any, any>;
26
25
  /**
27
26
  * Recursively serializes resolver results for transport across the network.
28
27
  */
@@ -31,15 +30,15 @@ type Serializable<T> = T extends Date ? string : T extends Array<infer U> ? Arra
31
30
  * Server-side mirror of a view definition describing how to select and resolve
32
31
  * fields when fulfilling a client request.
33
32
  */
34
- type DataView<Item$1 extends AnyRecord> = {
35
- fields: Record<string, DataField<Item$1>>;
33
+ type DataView<Item extends AnyRecord> = {
34
+ fields: Record<string, DataField<Item>>;
36
35
  kind?: 'resolver' | 'list';
37
36
  typeName: string;
38
37
  };
39
38
  /**
40
39
  * Convenience type for declaring the fields of a server data view.
41
40
  */
42
- type DataViewConfig<Item$1 extends AnyRecord> = Record<string, DataField<Item$1>>;
41
+ type DataViewConfig<Item extends AnyRecord> = Record<string, DataField<Item>>;
43
42
  /**
44
43
  * Declares a server data view that exposes an object's available fields to the client.
45
44
  *
@@ -49,27 +48,27 @@ type DataViewConfig<Item$1 extends AnyRecord> = Record<string, DataField<Item$1>
49
48
  * title: true,
50
49
  * });
51
50
  */
52
- declare function dataView<Item$1 extends AnyRecord>(typeName: string): <Fields extends DataViewConfig<Item$1>>(fields: Fields) => DataView<Item$1> & {
51
+ declare function dataView<Item extends AnyRecord>(typeName: string): <Fields extends DataViewConfig<Item>>(fields: Fields) => DataView<Item> & {
53
52
  readonly [dataViewFieldsKey]: Fields;
54
53
  };
55
54
  /**
56
55
  * Marks a data view as a list resolver so the server can respond with
57
56
  * connection information.
58
57
  */
59
- declare const list: <Item$1 extends AnyRecord>(view: DataView<Item$1>) => {
58
+ declare const list: <Item extends AnyRecord>(view: DataView<Item>) => {
60
59
  kind: "list";
61
- fields: Record<string, DataField<Item$1>>;
60
+ fields: Record<string, DataField<Item>>;
62
61
  typeName: string;
63
62
  };
64
63
  /**
65
64
  * Declares a resolver field inside a data view, optionally providing a
66
65
  * selection for any data dependencies.
67
66
  */
68
- declare function resolver<Item$1 extends AnyRecord, Result = unknown, Context = unknown>(config: {
69
- authorize?: ResolverAuthorize<Item$1, Context>;
70
- resolve: ResolverResolve<Item$1, Result, Context>;
67
+ declare function resolver<Item extends AnyRecord, Result = unknown, Context = unknown>(config: {
68
+ authorize?: ResolverAuthorize<Item, Context>;
69
+ resolve: ResolverResolve<Item, Result, Context>;
71
70
  select?: ResolverSelect<Context>;
72
- }): ResolverField<Item$1, Result, Context>;
71
+ }): ResolverField<Item, Result, Context>;
73
72
  type NonNullish<T> = Exclude<T, null | undefined>;
74
73
  type WithNullish<Original, Value> = null extends Original ? undefined extends Original ? Value | null | undefined : Value | null : undefined extends Original ? Value | undefined : Value;
75
74
  type ResolverResult<Field> = Field extends ResolverField<AnyRecord, any, any> ? Field['authorize'] extends ResolverAuthorize<any, any> ? Awaited<ReturnType<Field['resolve']>> | null : Awaited<ReturnType<Field['resolve']>> : never;
@@ -77,7 +76,7 @@ type RelationResult<ItemField, V extends DataView<AnyRecord>> = NonNullish<ItemF
77
76
  type ViewFieldConfig<V extends DataView<AnyRecord>> = V extends {
78
77
  readonly [dataViewFieldsKey]: infer Fields;
79
78
  } ? Fields : V['fields'];
80
- type RawFieldResult<Item$1 extends AnyRecord, Key extends PropertyKey, Field extends DataField<Item$1>> = Field extends true ? Key extends keyof Item$1 ? Item$1[Key] : never : Field extends DataView<infer ChildItem> ? Key extends keyof Item$1 ? RelationResult<Item$1[Key], DataView<ChildItem>> : never : Field extends ResolverField<Item$1, any, any> ? ResolverResult<Field> : never;
79
+ type RawFieldResult<Item extends AnyRecord, Key extends PropertyKey, Field extends DataField<Item>> = Field extends true ? Key extends keyof Item ? Item[Key] : never : Field extends DataView<infer ChildItem> ? Key extends keyof Item ? RelationResult<Item[Key], DataView<ChildItem>> : never : Field extends ResolverField<Item, any, any> ? ResolverResult<Field> : never;
81
80
  type RawDataViewResult<V extends DataView<AnyRecord>> = V extends DataView<infer Item> ? { [K in keyof ViewFieldConfig<V>]: RawFieldResult<Item, K, ViewFieldConfig<V>[K]> } : never;
82
81
  type DataViewResult<V extends DataView<AnyRecord>> = Serializable<RawDataViewResult<V>>;
83
82
  type WithTypename<T, Name extends string> = T & {
@@ -91,7 +90,7 @@ type Entity<TView extends DataView<AnyRecord>, Name extends string, Replacements
91
90
  * Builds a resolver that applies a client's selection to a server data view,
92
91
  * filtering fields, running nested resolvers, and shaping selects.
93
92
  */
94
- declare function createResolver<Item$1 extends AnyRecord, Context = unknown>({
93
+ declare function createResolver<Item extends AnyRecord, Context = unknown>({
95
94
  args,
96
95
  ctx,
97
96
  select: initialSelect,
@@ -100,9 +99,9 @@ declare function createResolver<Item$1 extends AnyRecord, Context = unknown>({
100
99
  args?: AnyRecord;
101
100
  ctx?: Context;
102
101
  select: Iterable<string>;
103
- view: DataView<Item$1>;
102
+ view: DataView<Item>;
104
103
  }): {
105
- resolve: (item: Item$1) => Promise<AnyRecord>;
104
+ resolve: (item: Item) => Promise<AnyRecord>;
106
105
  resolveMany: (items: Array<AnyRecord>) => Promise<Array<AnyRecord>>;
107
106
  select: Record<string, unknown>;
108
107
  };
@@ -117,8 +116,43 @@ type ConnectionCursor = string;
117
116
  /**
118
117
  * Connection item including the node and opaque cursor.
119
118
  */
120
-
121
- type ProcedureLike<TContext> = TRPCProcedureBuilder<TContext, any, any, any, any, any, any, false>;
119
+ type ConnectionItem<TNode> = {
120
+ cursor: ConnectionCursor;
121
+ node: TNode;
122
+ };
123
+ /**
124
+ * Pagination metadata returned with connection lists.
125
+ */
126
+ type ConnectionPagination = {
127
+ hasNext: boolean;
128
+ hasPrevious: boolean;
129
+ nextCursor?: ConnectionCursor;
130
+ previousCursor?: ConnectionCursor;
131
+ };
132
+ /**
133
+ * Connection payload that mirrors what the client expects for list fields.
134
+ */
135
+ type ConnectionResult<TNode> = {
136
+ items: Array<ConnectionItem<TNode>>;
137
+ pagination: ConnectionPagination;
138
+ };
139
+ type ProcedureLike = {
140
+ input: (schema: any) => {
141
+ query: (resolver: (options: any) => unknown) => unknown;
142
+ };
143
+ };
144
+ type ProcedureContext<TProcedure> = TProcedure extends {
145
+ input: (schema: any) => {
146
+ query: (resolver: (options: {
147
+ ctx: infer TContext;
148
+ }) => unknown) => unknown;
149
+ };
150
+ } ? TContext : unknown;
151
+ type ConnectionProcedure<TInput, TOutput> = QueryProcedure<{
152
+ input: TInput;
153
+ meta: unknown;
154
+ output: TOutput;
155
+ }>;
122
156
  type QueryFn<TContext, TItem, TInput extends ConnectionInput> = (options: {
123
157
  ctx: TContext;
124
158
  cursor?: ConnectionCursor;
@@ -144,24 +178,17 @@ declare const connectionInput: z.ZodObject<{
144
178
  * Converts an array of nodes into a list view connection result the client
145
179
  * can normalize.
146
180
  */
147
-
148
181
  /**
149
182
  * Wraps a tRPC procedure to handle cursor-based pagination with consistent
150
183
  * connection semantics.
151
184
  */
152
- declare const withConnection: <TContext>(procedure: ProcedureLike<TContext>) => <TItem, TNode = TItem, TAdditionalInput extends AdditionalInputSchema | undefined = undefined>({
153
- defaultSize,
154
- getCursor,
155
- input: additionalInput,
156
- map,
157
- query
158
- }: {
185
+ declare function withConnection<TProcedure extends ProcedureLike>(procedure: TProcedure): <TItem, TNode = TItem, TAdditionalInput extends AdditionalInputSchema | undefined = undefined>(options: {
159
186
  defaultSize?: number;
160
187
  getCursor?: (node: TNode) => ConnectionCursor;
161
188
  input?: TAdditionalInput;
162
- map?: MapFn<TContext, TItem, TNode, ConnectionInputWithAdditional<TAdditionalInput>>;
163
- query: QueryFn<TContext, TItem, ConnectionInputWithAdditional<TAdditionalInput>>;
164
- }) => ReturnType<ReturnType<ProcedureLike<TContext>["input"]>["query"]>;
189
+ map?: MapFn<ProcedureContext<TProcedure>, TItem, TNode, ConnectionInputWithAdditional<TAdditionalInput>>;
190
+ query: QueryFn<ProcedureContext<TProcedure>, TItem, ConnectionInputWithAdditional<TAdditionalInput>>;
191
+ }) => ConnectionProcedure<ConnectionInputWithAdditional<TAdditionalInput>, ConnectionResult<TNode>>;
165
192
  //#endregion
166
193
  //#region src/server/input.d.ts
167
194
  declare const byIdInput: z.ZodObject<{
package/lib/server.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as isRecord } from "./record-DnhZuvUe.mjs";
1
+ import { t as isRecord$1 } from "./record-DnhZuvUe.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/server/prismaSelect.ts
@@ -14,7 +14,7 @@ const toPrismaArgs = (args$1) => {
14
14
  }
15
15
  return prismaArgs;
16
16
  };
17
- const isRecord$1 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
17
+ const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
18
18
  /**
19
19
  * Narrows nested args to the slice relevant for a particular selection path.
20
20
  */
@@ -23,10 +23,10 @@ function getScopedArgs(args$1, path) {
23
23
  const segments = path.split(".");
24
24
  let current = args$1;
25
25
  for (const segment of segments) {
26
- if (!isRecord$1(current)) return;
26
+ if (!isRecord(current)) return;
27
27
  current = current[segment];
28
28
  }
29
- return isRecord$1(current) ? current : void 0;
29
+ return isRecord(current) ? current : void 0;
30
30
  }
31
31
  /**
32
32
  * Builds a Prisma `select` object from flattened selection paths and optional
@@ -80,14 +80,14 @@ const paginationArgsSchema = z.strictObject({
80
80
  first: z.number().int().positive().optional(),
81
81
  last: z.number().int().positive().optional()
82
82
  }).partial().refine(({ after, before }) => !(after && before), "Connection args can't include both 'after' and 'before'.").refine(({ first, last }) => !(first && last), "Connection args can't include both 'first' and 'last'.").refine(({ before, last }) => !last || before !== void 0, "Connection args using 'last' must also include 'before'.");
83
- const extractPaginationArgs = (args$1) => args$1 ? Object.fromEntries(Object.entries(args$1).filter(([key]) => paginationArgKeys.has(key))) : {};
83
+ const extractPaginationArgs = (args) => args ? Object.fromEntries(Object.entries(args).filter(([key]) => paginationArgKeys.has(key))) : {};
84
84
  /**
85
85
  * Converts an array of nodes into a list view connection result the client
86
86
  * can normalize.
87
87
  */
88
- function arrayToConnection(nodes, { args: args$1, getCursor = (node) => String(node.id) } = {}) {
88
+ function arrayToConnection(nodes, { args, getCursor = (node) => String(node.id) } = {}) {
89
89
  if (!nodes) return;
90
- const paginationArgs = paginationArgsSchema.parse(extractPaginationArgs(args$1));
90
+ const paginationArgs = paginationArgsSchema.parse(extractPaginationArgs(args));
91
91
  if (Object.keys(paginationArgs).length === 0) return {
92
92
  items: nodes.map((node) => ({
93
93
  cursor: getCursor(node),
@@ -130,8 +130,8 @@ const assignIfChanged = (current, key, next, existing) => {
130
130
  current[key] = next;
131
131
  return current;
132
132
  };
133
- function toConnectionResult({ args: args$1, item, path, view }) {
134
- if (!isRecord(item)) return item;
133
+ function toConnectionResult({ args, item, path, view }) {
134
+ if (!isRecord$1(item)) return item;
135
135
  let result = null;
136
136
  const base = () => result ? {
137
137
  ...item,
@@ -144,17 +144,17 @@ function toConnectionResult({ args: args$1, item, path, view }) {
144
144
  if (config.kind === "list") {
145
145
  if (!Array.isArray(current)) continue;
146
146
  const connection = arrayToConnection(current.map((item$1) => toConnectionResult({
147
- args: args$1,
147
+ args,
148
148
  item: item$1,
149
149
  path: nextPath,
150
150
  view: config
151
- })), { args: getScopedArgs(args$1, nextPath) });
151
+ })), { args: getScopedArgs(args, nextPath) });
152
152
  result = assignIfChanged(result, field, connection, current);
153
153
  continue;
154
154
  }
155
155
  if (Array.isArray(current)) {
156
156
  const wrapped = current.map((entry) => toConnectionResult({
157
- args: args$1,
157
+ args,
158
158
  item: entry,
159
159
  path: nextPath,
160
160
  view: config
@@ -162,9 +162,9 @@ function toConnectionResult({ args: args$1, item, path, view }) {
162
162
  result = assignIfChanged(result, field, wrapped, current);
163
163
  continue;
164
164
  }
165
- if (isRecord(current)) {
165
+ if (isRecord$1(current)) {
166
166
  const wrapped = toConnectionResult({
167
- args: args$1,
167
+ args,
168
168
  item: current,
169
169
  path: nextPath,
170
170
  view: config
@@ -177,50 +177,48 @@ function toConnectionResult({ args: args$1, item, path, view }) {
177
177
  ...result
178
178
  } : item;
179
179
  }
180
- /**
181
- * Wraps a tRPC procedure to handle cursor-based pagination with consistent
182
- * connection semantics.
183
- */
184
- const withConnection = (procedure) => ({ defaultSize = 20, getCursor = (node) => node.id, input: additionalInput, map, query }) => {
185
- const inputSchema = additionalInput ? connectionInput.extend({ args: connectionArgs.and(additionalInput) }) : connectionInput;
186
- return procedure.input(inputSchema).query(async (resolverOptions) => {
187
- const { ctx, input } = resolverOptions;
188
- const paginationArgs = paginationArgsSchema.parse(extractPaginationArgs(input.args));
189
- const isBackward = paginationArgs.before !== void 0 || paginationArgs.last !== void 0;
190
- const cursor = isBackward ? paginationArgs.before : paginationArgs.after;
191
- const direction = isBackward ? "backward" : "forward";
192
- const pageSize = paginationArgs.first ?? paginationArgs.last ?? defaultSize;
193
- const rawItems = await query({
194
- ctx,
195
- cursor,
196
- direction,
197
- input,
198
- skip: cursor ? 1 : void 0,
199
- take: pageSize + 1
180
+ function withConnection(procedure) {
181
+ return ({ defaultSize = 20, getCursor = (node) => node.id, input: additionalInput, map, query }) => {
182
+ const inputSchema = additionalInput ? connectionInput.extend({ args: connectionArgs.and(additionalInput) }) : connectionInput;
183
+ return procedure.input(inputSchema).query(async (resolverOptions) => {
184
+ const { ctx, input } = resolverOptions;
185
+ const paginationArgs = paginationArgsSchema.parse(extractPaginationArgs(input.args));
186
+ const isBackward = paginationArgs.before !== void 0 || paginationArgs.last !== void 0;
187
+ const cursor = isBackward ? paginationArgs.before : paginationArgs.after;
188
+ const direction = isBackward ? "backward" : "forward";
189
+ const pageSize = paginationArgs.first ?? paginationArgs.last ?? defaultSize;
190
+ const rawItems = await query({
191
+ ctx,
192
+ cursor,
193
+ direction,
194
+ input,
195
+ skip: cursor ? 1 : void 0,
196
+ take: pageSize + 1
197
+ });
198
+ const hasMore = rawItems.length > pageSize;
199
+ const limitedItems = isBackward ? rawItems.slice(Math.max(0, rawItems.length - pageSize)) : rawItems.slice(0, pageSize);
200
+ const items = (map ? await map({
201
+ ctx,
202
+ input,
203
+ items: limitedItems
204
+ }) : limitedItems).map((node) => ({
205
+ cursor: getCursor(node),
206
+ node
207
+ }));
208
+ const firstItem = items[0];
209
+ const lastItem = items.at(-1);
210
+ return {
211
+ items,
212
+ pagination: {
213
+ hasNext: isBackward ? Boolean(cursor) : hasMore,
214
+ hasPrevious: isBackward ? hasMore : Boolean(cursor),
215
+ nextCursor: lastItem?.cursor,
216
+ previousCursor: (isBackward ? hasMore : Boolean(cursor)) ? firstItem?.cursor : void 0
217
+ }
218
+ };
200
219
  });
201
- const hasMore = rawItems.length > pageSize;
202
- const limitedItems = isBackward ? rawItems.slice(Math.max(0, rawItems.length - pageSize)) : rawItems.slice(0, pageSize);
203
- const items = (map ? await map({
204
- ctx,
205
- input,
206
- items: limitedItems
207
- }) : limitedItems).map((node) => ({
208
- cursor: getCursor(node),
209
- node
210
- }));
211
- const firstItem = items[0];
212
- const lastItem = items.at(-1);
213
- return {
214
- items,
215
- pagination: {
216
- hasNext: isBackward ? Boolean(cursor) : hasMore,
217
- hasPrevious: isBackward ? hasMore : Boolean(cursor),
218
- nextCursor: lastItem?.cursor,
219
- previousCursor: (isBackward ? hasMore : Boolean(cursor)) ? firstItem?.cursor : void 0
220
- }
221
- };
222
- });
223
- };
220
+ };
221
+ }
224
222
 
225
223
  //#endregion
226
224
  //#region src/server/dataView.ts
@@ -266,7 +264,7 @@ function resolver(config) {
266
264
  const isResolverField = (field) => Boolean(field) && typeof field === "object" && "kind" in field && field.kind === "resolver";
267
265
  const isDataViewField = (field) => Boolean(field) && typeof field === "object" && "fields" in field;
268
266
  const filterToViewFields = (item, view, selectedPaths, prefix = null) => {
269
- if (!isRecord(item)) return item;
267
+ if (!isRecord$1(item)) return item;
270
268
  const filtered = {};
271
269
  for (const [field, config] of Object.entries(view.fields)) {
272
270
  const path = prefix ? `${prefix}.${field}` : field;
@@ -282,10 +280,10 @@ const filterToViewFields = (item, view, selectedPaths, prefix = null) => {
282
280
  const value = item[field];
283
281
  if (isDataViewField(config)) {
284
282
  if (Array.isArray(value)) {
285
- filtered[field] = value.map((entry) => isRecord(entry) ? filterToViewFields(entry, config, selectedPaths, path) : entry);
283
+ filtered[field] = value.map((entry) => isRecord$1(entry) ? filterToViewFields(entry, config, selectedPaths, path) : entry);
286
284
  continue;
287
285
  }
288
- if (isRecord(value)) {
286
+ if (isRecord$1(value)) {
289
287
  filtered[field] = filterToViewFields(value, config, selectedPaths, path);
290
288
  continue;
291
289
  }
@@ -297,7 +295,7 @@ const filterToViewFields = (item, view, selectedPaths, prefix = null) => {
297
295
  const mergeObject = (target, source) => {
298
296
  for (const [key, value] of Object.entries(source)) {
299
297
  const existing = target[key];
300
- if (isRecord(existing) && isRecord(value)) {
298
+ if (isRecord$1(existing) && isRecord$1(value)) {
301
299
  mergeObject(existing, value);
302
300
  continue;
303
301
  }
@@ -310,9 +308,9 @@ const ensureRelationSelect = (select, path) => {
310
308
  let current = select;
311
309
  for (const segment of segments) {
312
310
  const existing = current[segment];
313
- if (isRecord(existing) && "select" in existing) {
311
+ if (isRecord$1(existing) && "select" in existing) {
314
312
  const relation$1 = existing;
315
- if (!isRecord(relation$1.select)) relation$1.select = {};
313
+ if (!isRecord$1(relation$1.select)) relation$1.select = {};
316
314
  current = relation$1.select;
317
315
  continue;
318
316
  }
@@ -364,32 +362,32 @@ const assignPath = (node, segments, path, selectedPaths, view, allowedPaths) =>
364
362
  }
365
363
  };
366
364
  const collectResolvers = (node, select, args$1, context) => {
367
- for (const resolver$1 of node.resolvers.values()) {
368
- if (!resolver$1.select) continue;
369
- const addition = typeof resolver$1.select === "function" ? resolver$1.select({
365
+ for (const resolver of node.resolvers.values()) {
366
+ if (!resolver.select) continue;
367
+ const addition = typeof resolver.select === "function" ? resolver.select({
370
368
  args: args$1,
371
369
  context
372
- }) : resolver$1.select;
373
- if (addition && isRecord(addition)) mergeObject(ensureRelationSelect(select, node.path), addition);
370
+ }) : resolver.select;
371
+ if (addition && isRecord$1(addition)) mergeObject(ensureRelationSelect(select, node.path), addition);
374
372
  }
375
373
  for (const relation of node.relations.values()) collectResolvers(relation, select, args$1, context);
376
374
  };
377
375
  const resolveNode = async ({ item, node, options: resolverOptions }) => {
378
- if (!isRecord(item)) return item;
376
+ if (!isRecord$1(item)) return item;
379
377
  let result = null;
380
378
  const assign = (key, value) => {
381
379
  if (!result) result = { ...item };
382
380
  result[key] = value;
383
381
  };
384
382
  const getItem = () => result ?? item;
385
- for (const [field, resolver$1] of node.resolvers) {
386
- if (resolver$1.authorize) {
387
- if (!await resolver$1.authorize(getItem(), resolverOptions.context, resolverOptions.args)) {
383
+ for (const [field, resolver] of node.resolvers) {
384
+ if (resolver.authorize) {
385
+ if (!await resolver.authorize(getItem(), resolverOptions.context, resolverOptions.args)) {
388
386
  assign(field, null);
389
387
  continue;
390
388
  }
391
389
  }
392
- const value = await resolver$1.resolve(getItem(), resolverOptions.context, resolverOptions.args);
390
+ const value = await resolver.resolve(getItem(), resolverOptions.context, resolverOptions.args);
393
391
  if (value !== void 0) assign(field, value);
394
392
  }
395
393
  for (const [field, relationNode] of node.relations) {