@nkzw/fate 0.1.0 → 0.1.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/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/index.d.mts CHANGED
@@ -1,4 +1,4 @@
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-CNKGKRtz.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-Djlh7mMH.mjs";
2
2
 
3
3
  //#region src/root.d.ts
4
4
 
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;
@@ -689,39 +689,45 @@ function wrapMutation(client, identifier) {
689
689
  if (id$1 == null) throw new Error(`fate: Mutation '${identifier.key}' requires an 'id' to delete.`);
690
690
  client.deleteRecord(identifier.entity, id$1, snapshots, listSnapshots);
691
691
  }
692
- try {
693
- const result = await client.executeMutation(identifier.key, input, selection, {
694
- args,
695
- plan
696
- });
697
- if (result && typeof result === "object" && (!deleteRecord || Boolean(view$1))) {
698
- const select = collectImplicitSelectedPaths(result);
699
- const pendingMask = optimisticEntityId ? client.getPendingOptimisticMask(optimisticEntityId, { excludeToken: optimisticToken }) : null;
700
- const filteredSelection = optimisticEntityId ? client.filterSelectionForPendingOptimistics(optimisticEntityId, select, { excludeToken: optimisticToken }) : select;
701
- client.write(identifier.entity, result, filteredSelection, void 0, plan, null, pendingMask, insert);
702
- if (deleteRecord && id$1 != null) client.deleteRecord(identifier.entity, id$1);
703
- const resultId = maybeGetId(config.getId, result);
704
- if (optimisticRecordId != null && resultId != null && optimisticRecordId !== resultId) client.deleteRecord(identifier.entity, optimisticRecordId);
705
- }
706
- return {
707
- error: void 0,
708
- result
709
- };
710
- } catch (error) {
711
- client.clearOptimisticUpdate(optimisticToken);
712
- if (snapshots.size > 0) for (const [id$2, snapshot] of snapshots) client.restore(id$2, snapshot);
713
- if (listSnapshots && listSnapshots.size > 0) for (const [name, list] of listSnapshots) client.restoreList(name, list);
714
- if (error instanceof Error) {
715
- const { data } = error;
716
- if ((data ? categorizeTRPCError(getHTTPStatusCodeFromError(data)) : "boundary") === "boundary") throw error;
692
+ const performMutation = async () => {
693
+ try {
694
+ const result = await client.executeMutation(identifier.key, input, selection, {
695
+ args,
696
+ plan
697
+ });
698
+ if (result && typeof result === "object" && (!deleteRecord || Boolean(view$1))) {
699
+ const select = collectImplicitSelectedPaths(result);
700
+ const pendingMask = optimisticEntityId ? client.getPendingOptimisticMask(optimisticEntityId, { excludeToken: optimisticToken }) : null;
701
+ const filteredSelection = optimisticEntityId ? client.filterSelectionForPendingOptimistics(optimisticEntityId, select, { excludeToken: optimisticToken }) : select;
702
+ client.write(identifier.entity, result, filteredSelection, void 0, plan, null, pendingMask, insert);
703
+ if (deleteRecord && id$1 != null) client.deleteRecord(identifier.entity, id$1);
704
+ const resultId = maybeGetId(config.getId, result);
705
+ if (optimisticEntityId && resultId != null) client.resolveOptimisticEntity(optimisticEntityId, toEntityId(identifier.entity, resultId));
706
+ if (optimisticRecordId != null && resultId != null && optimisticRecordId !== resultId) client.deleteRecord(identifier.entity, optimisticRecordId);
707
+ }
717
708
  return {
718
- error,
719
- result: void 0
709
+ error: void 0,
710
+ result
720
711
  };
721
- } else throw new Error(`fate: Mutation '${identifier.key}' failed.`);
722
- } finally {
723
- client.clearOptimisticUpdate(optimisticToken);
724
- }
712
+ } catch (error) {
713
+ client.clearOptimisticUpdate(optimisticToken);
714
+ if (snapshots.size > 0) for (const [id$2, snapshot] of snapshots) client.restore(id$2, snapshot);
715
+ if (listSnapshots && listSnapshots.size > 0) for (const [name, list] of listSnapshots) client.restoreList(name, list);
716
+ if (error instanceof Error) {
717
+ const { data } = error;
718
+ if ((data ? categorizeTRPCError(getHTTPStatusCodeFromError(data)) : "boundary") === "boundary") throw error;
719
+ return {
720
+ error,
721
+ result: void 0
722
+ };
723
+ } else throw new Error(`fate: Mutation '${identifier.key}' failed.`);
724
+ } finally {
725
+ client.clearOptimisticUpdate(optimisticToken);
726
+ }
727
+ };
728
+ const mutationPromise = performMutation();
729
+ if (optimisticEntityId) client.registerPendingOptimisticMutation(optimisticEntityId, mutationPromise);
730
+ return mutationPromise;
725
731
  };
726
732
  }
727
733
  function categorizeTRPCError(statusCode) {
@@ -1049,8 +1055,10 @@ var FateClient = class {
1049
1055
  this.parentLists = /* @__PURE__ */ new Map();
1050
1056
  this.rootLists = /* @__PURE__ */ new Map();
1051
1057
  this.pending = /* @__PURE__ */ new Map();
1058
+ this.pendingOptimisticMutations = /* @__PURE__ */ new Map();
1052
1059
  this.optimisticMasks = /* @__PURE__ */ new Map();
1053
1060
  this.optimisticByEntity = /* @__PURE__ */ new Map();
1061
+ this.optimisticEntityResolutions = /* @__PURE__ */ new Map();
1054
1062
  this.optimisticTokenCounter = 0;
1055
1063
  this.requests = /* @__PURE__ */ new Map();
1056
1064
  this.rootRequests = /* @__PURE__ */ new Map();
@@ -1177,6 +1185,11 @@ var FateClient = class {
1177
1185
  }
1178
1186
  if (type == null) throw new Error(`fate: Invalid view reference. Expected '__typename' to be provided as part of the reference, received '${JSON.stringify(ref)}'.`);
1179
1187
  const entityId = toEntityId(type, id$1);
1188
+ const resolvedEntityId = this.optimisticEntityResolutions.get(entityId) ?? null;
1189
+ if (resolvedEntityId && resolvedEntityId !== entityId) {
1190
+ const { id: resolvedId, type: resolvedType } = parseEntityId(resolvedEntityId);
1191
+ return this.readView(view$1, createRef(resolvedType, resolvedId, view$1));
1192
+ }
1180
1193
  const viewNames = getViewNames(view$1);
1181
1194
  const refViews = ref[ViewsTag];
1182
1195
  if (!refViews || ![...viewNames].every((name) => refViews.has(name))) {
@@ -1204,6 +1217,14 @@ var FateClient = class {
1204
1217
  }
1205
1218
  if (missing.size > 0) {
1206
1219
  const key = this.pendingKey(entityId, missing);
1220
+ const pendingOptimistic = this.getPendingOptimisticMutations(entityId);
1221
+ if (pendingOptimistic) {
1222
+ const pending = this.pending.get(key);
1223
+ if (pending) return pending;
1224
+ const promise$1 = Promise.all(pendingOptimistic).then(() => this.readView(view$1, ref)).finally(() => this.pending.delete(key));
1225
+ this.pending.set(key, promise$1);
1226
+ return promise$1;
1227
+ }
1207
1228
  if (this.stalledRequests.has(key)) return resolveSnapshot();
1208
1229
  const pendingPromise = this.pending.get(key) || null;
1209
1230
  if (pendingPromise) return pendingPromise;
@@ -1257,6 +1278,24 @@ var FateClient = class {
1257
1278
  } : void 0
1258
1279
  };
1259
1280
  }
1281
+ registerPendingOptimisticMutation(entityId, promise) {
1282
+ let entries = this.pendingOptimisticMutations.get(entityId);
1283
+ if (!entries) {
1284
+ entries = /* @__PURE__ */ new Set();
1285
+ this.pendingOptimisticMutations.set(entityId, entries);
1286
+ }
1287
+ const trackedPromise = promise.catch(() => void 0);
1288
+ entries.add(trackedPromise);
1289
+ trackedPromise.finally(() => {
1290
+ const current = this.pendingOptimisticMutations.get(entityId);
1291
+ if (!current) return;
1292
+ current.delete(trackedPromise);
1293
+ if (current.size === 0) this.pendingOptimisticMutations.delete(entityId);
1294
+ });
1295
+ }
1296
+ resolveOptimisticEntity(optimisticEntityId, resolvedEntityId) {
1297
+ this.optimisticEntityResolutions.set(optimisticEntityId, resolvedEntityId);
1298
+ }
1260
1299
  registerOptimisticUpdate(entityId, select) {
1261
1300
  if (!entityId || select.size === 0) return null;
1262
1301
  const mask = fromPaths(select);
@@ -1298,6 +1337,10 @@ var FateClient = class {
1298
1337
  }
1299
1338
  return mask;
1300
1339
  }
1340
+ getPendingOptimisticMutations(entityId) {
1341
+ const pending = this.pendingOptimisticMutations.get(entityId);
1342
+ return pending && pending.size > 0 ? [...pending] : null;
1343
+ }
1301
1344
  filterSelectionForPendingOptimistics(entityId, select, options = {}) {
1302
1345
  if (!entityId || select.size === 0) return select;
1303
1346
  const pendingMask = this.getPendingOptimisticMask(entityId, options);
package/lib/server.d.mts CHANGED
@@ -1,6 +1,5 @@
1
- import { t as AnyRecord } from "./types-CNKGKRtz.mjs";
1
+ import { W as QueryProcedure, t as AnyRecord } from "./types-Djlh7mMH.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;
@@ -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;
@@ -149,19 +183,13 @@ declare const connectionInput: z.ZodObject<{
149
183
  * Wraps a tRPC procedure to handle cursor-based pagination with consistent
150
184
  * connection semantics.
151
185
  */
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
- }: {
186
+ declare function withConnection<TProcedure extends ProcedureLike>(procedure: TProcedure): <TItem, TNode = TItem, TAdditionalInput extends AdditionalInputSchema | undefined = undefined>(options: {
159
187
  defaultSize?: number;
160
188
  getCursor?: (node: TNode) => ConnectionCursor;
161
189
  input?: TAdditionalInput;
162
- map?: MapFn<TContext, TItem, TNode, ConnectionInputWithAdditional<TAdditionalInput>>;
163
- query: QueryFn<TContext, TItem, ConnectionInputWithAdditional<TAdditionalInput>>;
164
- }) => ReturnType<ReturnType<ProcedureLike<TContext>["input"]>["query"]>;
190
+ map?: MapFn<ProcedureContext<TProcedure>, TItem, TNode, ConnectionInputWithAdditional<TAdditionalInput>>;
191
+ query: QueryFn<ProcedureContext<TProcedure>, TItem, ConnectionInputWithAdditional<TAdditionalInput>>;
192
+ }) => ConnectionProcedure<ConnectionInputWithAdditional<TAdditionalInput>, ConnectionResult<TNode>>;
165
193
  //#endregion
166
194
  //#region src/server/input.d.ts
167
195
  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
@@ -131,7 +131,7 @@ const assignIfChanged = (current, key, next, existing) => {
131
131
  return current;
132
132
  };
133
133
  function toConnectionResult({ args: args$1, item, path, view }) {
134
- if (!isRecord(item)) return item;
134
+ if (!isRecord$1(item)) return item;
135
135
  let result = null;
136
136
  const base = () => result ? {
137
137
  ...item,
@@ -162,7 +162,7 @@ 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
167
  args: args$1,
168
168
  item: current,
@@ -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
  }
@@ -370,12 +368,12 @@ const collectResolvers = (node, select, args$1, context) => {
370
368
  args: args$1,
371
369
  context
372
370
  }) : resolver$1.select;
373
- if (addition && isRecord(addition)) mergeObject(ensureRelationSelect(select, node.path), addition);
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 };
@@ -1,5 +1,4 @@
1
1
  import { TRPCClient } from "@trpc/client";
2
- import { AnyRouter } from "@trpc/server";
3
2
 
4
3
  //#region src/mask.d.ts
5
4
  type FieldMask = {
@@ -70,6 +69,602 @@ declare class Store {
70
69
  restore(id: EntityId, snapshot: Snapshot): void;
71
70
  }
72
71
  //#endregion
72
+ //#region ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/index.d-D4qZxQJh.d.mts
73
+ //#region src/observable/types.d.ts
74
+ interface Unsubscribable {
75
+ unsubscribe(): void;
76
+ }
77
+ interface Subscribable<TValue$1, TError> {
78
+ subscribe(observer: Partial<Observer<TValue$1, TError>>): Unsubscribable;
79
+ }
80
+ interface Observable<TValue$1, TError> extends Subscribable<TValue$1, TError> {
81
+ pipe(): Observable<TValue$1, TError>;
82
+ pipe<TValue1, TError1>(op1: OperatorFunction<TValue$1, TError, TValue1, TError1>): Observable<TValue1, TError1>;
83
+ pipe<TValue1, TError1, TValue2, TError2>(op1: OperatorFunction<TValue$1, TError, TValue1, TError1>, op2: OperatorFunction<TValue1, TError1, TValue2, TError2>): Observable<TValue2, TError2>;
84
+ pipe<TValue1, TError1, TValue2, TError2, TValue3, TError3>(op1: OperatorFunction<TValue$1, TError, TValue1, TError1>, op2: OperatorFunction<TValue1, TError1, TValue2, TError2>, op3: OperatorFunction<TValue2, TError2, TValue3, TError3>): Observable<TValue2, TError2>;
85
+ pipe<TValue1, TError1, TValue2, TError2, TValue3, TError3, TValue4, TError4>(op1: OperatorFunction<TValue$1, TError, TValue1, TError1>, op2: OperatorFunction<TValue1, TError1, TValue2, TError2>, op3: OperatorFunction<TValue2, TError2, TValue3, TError3>, op4: OperatorFunction<TValue3, TError3, TValue4, TError4>): Observable<TValue2, TError2>;
86
+ pipe<TValue1, TError1, TValue2, TError2, TValue3, TError3, TValue4, TError4, TValue5, TError5>(op1: OperatorFunction<TValue$1, TError, TValue1, TError1>, op2: OperatorFunction<TValue1, TError1, TValue2, TError2>, op3: OperatorFunction<TValue2, TError2, TValue3, TError3>, op4: OperatorFunction<TValue3, TError3, TValue4, TError4>, op5: OperatorFunction<TValue4, TError4, TValue5, TError5>): Observable<TValue2, TError2>;
87
+ }
88
+ interface Observer<TValue$1, TError> {
89
+ next: (value: TValue$1) => void;
90
+ error: (err: TError) => void;
91
+ complete: () => void;
92
+ }
93
+ type UnaryFunction<TSource, TReturn> = (source: TSource) => TReturn;
94
+ type OperatorFunction<TValueBefore, TErrorBefore, TValueAfter, TErrorAfter> = UnaryFunction<Subscribable<TValueBefore, TErrorBefore>, Subscribable<TValueAfter, TErrorAfter>>;
95
+ //#endregion
96
+ //#region ../../node_modules/.pnpm/@trpc+server@11.8.1_typescript@5.9.3/node_modules/@trpc/server/dist/unstable-core-do-not-import.d-CjQPvBRI.d.mts
97
+ /**
98
+ * @public
99
+ */
100
+ type MaybePromise<TType> = Promise<TType> | TType;
101
+ /**
102
+ * @internal
103
+ * Returns the raw input type of a procedure
104
+ */
105
+ type GetRawInputFn = () => Promise<unknown>;
106
+ type ValueOf<TObj> = TObj[keyof TObj];
107
+ //#endregion
108
+ //#region src/unstable-core-do-not-import/rpc/codes.d.ts
109
+ /**
110
+ * JSON-RPC 2.0 Error codes
111
+ *
112
+ * `-32000` to `-32099` are reserved for implementation-defined server-errors.
113
+ * For tRPC we're copying the last digits of HTTP 4XX errors.
114
+ */
115
+ declare const TRPC_ERROR_CODES_BY_KEY: {
116
+ /**
117
+ * Invalid JSON was received by the server.
118
+ * An error occurred on the server while parsing the JSON text.
119
+ */
120
+ readonly PARSE_ERROR: -32700;
121
+ /**
122
+ * The JSON sent is not a valid Request object.
123
+ */
124
+ readonly BAD_REQUEST: -32600;
125
+ readonly INTERNAL_SERVER_ERROR: -32603;
126
+ readonly NOT_IMPLEMENTED: -32603;
127
+ readonly BAD_GATEWAY: -32603;
128
+ readonly SERVICE_UNAVAILABLE: -32603;
129
+ readonly GATEWAY_TIMEOUT: -32603;
130
+ readonly UNAUTHORIZED: -32001;
131
+ readonly PAYMENT_REQUIRED: -32002;
132
+ readonly FORBIDDEN: -32003;
133
+ readonly NOT_FOUND: -32004;
134
+ readonly METHOD_NOT_SUPPORTED: -32005;
135
+ readonly TIMEOUT: -32008;
136
+ readonly CONFLICT: -32009;
137
+ readonly PRECONDITION_FAILED: -32012;
138
+ readonly PAYLOAD_TOO_LARGE: -32013;
139
+ readonly UNSUPPORTED_MEDIA_TYPE: -32015;
140
+ readonly UNPROCESSABLE_CONTENT: -32022;
141
+ readonly PRECONDITION_REQUIRED: -32028;
142
+ readonly TOO_MANY_REQUESTS: -32029;
143
+ readonly CLIENT_CLOSED_REQUEST: -32099;
144
+ };
145
+ type TRPC_ERROR_CODE_NUMBER = ValueOf<typeof TRPC_ERROR_CODES_BY_KEY>;
146
+ type TRPC_ERROR_CODE_KEY = keyof typeof TRPC_ERROR_CODES_BY_KEY;
147
+ /**
148
+ * tRPC error codes that are considered retryable
149
+ * With out of the box SSE, the client will reconnect when these errors are encountered
150
+ */
151
+
152
+ declare class TRPCError extends Error {
153
+ readonly cause?: Error;
154
+ readonly code: "PARSE_ERROR" | "BAD_REQUEST" | "INTERNAL_SERVER_ERROR" | "NOT_IMPLEMENTED" | "BAD_GATEWAY" | "SERVICE_UNAVAILABLE" | "GATEWAY_TIMEOUT" | "UNAUTHORIZED" | "PAYMENT_REQUIRED" | "FORBIDDEN" | "NOT_FOUND" | "METHOD_NOT_SUPPORTED" | "TIMEOUT" | "CONFLICT" | "PRECONDITION_FAILED" | "PAYLOAD_TOO_LARGE" | "UNSUPPORTED_MEDIA_TYPE" | "UNPROCESSABLE_CONTENT" | "PRECONDITION_REQUIRED" | "TOO_MANY_REQUESTS" | "CLIENT_CLOSED_REQUEST";
155
+ constructor(opts: {
156
+ message?: string;
157
+ code: TRPC_ERROR_CODE_KEY;
158
+ cause?: unknown;
159
+ });
160
+ }
161
+ //# sourceMappingURL=TRPCError.d.ts.map
162
+ //#endregion
163
+ //#region src/vendor/standard-schema-v1/spec.d.ts
164
+ /**
165
+ *
166
+ * @see https://github.com/standard-schema/standard-schema/blob/main/packages/spec/src/index.ts
167
+ */
168
+ /** The Standard Schema interface. */
169
+ interface StandardSchemaV1<Input$1 = unknown, Output$1 = Input$1> {
170
+ /** The Standard Schema properties. */
171
+ readonly '~standard': StandardSchemaV1.Props<Input$1, Output$1>;
172
+ }
173
+ declare namespace StandardSchemaV1 {
174
+ /** The Standard Schema properties interface. */
175
+ interface Props<Input$1 = unknown, Output$1 = Input$1> {
176
+ /** The version number of the standard. */
177
+ readonly version: 1;
178
+ /** The vendor name of the schema library. */
179
+ readonly vendor: string;
180
+ /** Validates unknown input values. */
181
+ readonly validate: (value: unknown) => Result<Output$1> | Promise<Result<Output$1>>;
182
+ /** Inferred types associated with the schema. */
183
+ readonly types?: Types<Input$1, Output$1> | undefined;
184
+ }
185
+ /** The result interface of the validate function. */
186
+ type Result<Output$1> = SuccessResult<Output$1> | FailureResult;
187
+ /** The result interface if validation succeeds. */
188
+ interface SuccessResult<Output$1> {
189
+ /** The typed output value. */
190
+ readonly value: Output$1;
191
+ /** The non-existent issues. */
192
+ readonly issues?: undefined;
193
+ }
194
+ /** The result interface if validation fails. */
195
+ interface FailureResult {
196
+ /** The issues of failed validation. */
197
+ readonly issues: ReadonlyArray<Issue>;
198
+ }
199
+ /** The issue interface of the failure output. */
200
+ interface Issue {
201
+ /** The error message of the issue. */
202
+ readonly message: string;
203
+ /** The path of the issue, if any. */
204
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
205
+ }
206
+ /** The path segment interface of the issue. */
207
+ interface PathSegment {
208
+ /** The key representing a path segment. */
209
+ readonly key: PropertyKey;
210
+ }
211
+ /** The Standard Schema types interface. */
212
+ interface Types<Input$1 = unknown, Output$1 = Input$1> {
213
+ /** The input type of the schema. */
214
+ readonly input: Input$1;
215
+ /** The output type of the schema. */
216
+ readonly output: Output$1;
217
+ }
218
+ /** Infers the input type of a Standard Schema. */
219
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
220
+ /** Infers the output type of a Standard Schema. */
221
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
222
+ }
223
+ //# sourceMappingURL=spec.d.ts.map
224
+ //#endregion
225
+ //#region src/unstable-core-do-not-import/parser.d.ts
226
+ type ParserZodEsque<TInput, TParsedInput> = {
227
+ _input: TInput;
228
+ _output: TParsedInput;
229
+ };
230
+ type ParserValibotEsque<TInput, TParsedInput> = {
231
+ schema: {
232
+ _types?: {
233
+ input: TInput;
234
+ output: TParsedInput;
235
+ };
236
+ };
237
+ };
238
+ type ParserArkTypeEsque<TInput, TParsedInput> = {
239
+ inferIn: TInput;
240
+ infer: TParsedInput;
241
+ };
242
+ type ParserStandardSchemaEsque<TInput, TParsedInput> = StandardSchemaV1<TInput, TParsedInput>;
243
+ type ParserMyZodEsque<TInput> = {
244
+ parse: (input: any) => TInput;
245
+ };
246
+ type ParserSuperstructEsque<TInput> = {
247
+ create: (input: unknown) => TInput;
248
+ };
249
+ type ParserCustomValidatorEsque<TInput> = (input: unknown) => Promise<TInput> | TInput;
250
+ type ParserYupEsque<TInput> = {
251
+ validateSync: (input: unknown) => TInput;
252
+ };
253
+ type ParserScaleEsque<TInput> = {
254
+ assert(value: unknown): asserts value is TInput;
255
+ };
256
+ type ParserWithoutInput<TInput> = ParserCustomValidatorEsque<TInput> | ParserMyZodEsque<TInput> | ParserScaleEsque<TInput> | ParserSuperstructEsque<TInput> | ParserYupEsque<TInput>;
257
+ type ParserWithInputOutput<TInput, TParsedInput> = ParserZodEsque<TInput, TParsedInput> | ParserValibotEsque<TInput, TParsedInput> | ParserArkTypeEsque<TInput, TParsedInput> | ParserStandardSchemaEsque<TInput, TParsedInput>;
258
+ type Parser = ParserWithInputOutput<any, any> | ParserWithoutInput<any>;
259
+ /**
260
+ * @internal
261
+ */
262
+ interface ProcedureCallOptions<TContext$1> {
263
+ ctx: TContext$1;
264
+ getRawInput: GetRawInputFn;
265
+ input?: unknown;
266
+ path: string;
267
+ type: ProcedureType;
268
+ signal: AbortSignal | undefined;
269
+ }
270
+ //#endregion
271
+ //#region src/unstable-core-do-not-import/procedure.d.ts
272
+ declare const procedureTypes: readonly ["query", "mutation", "subscription"];
273
+ /**
274
+ * @public
275
+ */
276
+ type ProcedureType = (typeof procedureTypes)[number];
277
+ interface BuiltProcedureDef {
278
+ meta: unknown;
279
+ input: unknown;
280
+ output: unknown;
281
+ }
282
+ /**
283
+ *
284
+ * @internal
285
+ */
286
+ interface Procedure<TType extends ProcedureType, TDef extends BuiltProcedureDef> {
287
+ _def: {
288
+ /**
289
+ * These are just types, they can't be used at runtime
290
+ * @internal
291
+ */
292
+ $types: {
293
+ input: TDef['input'];
294
+ output: TDef['output'];
295
+ };
296
+ procedure: true;
297
+ type: TType;
298
+ /**
299
+ * @internal
300
+ * Meta is not inferrable on individual procedures, only on the router
301
+ */
302
+ meta: unknown;
303
+ experimental_caller: boolean;
304
+ /**
305
+ * The input parsers for the procedure
306
+ */
307
+ inputs: Parser[];
308
+ };
309
+ meta: TDef['meta'];
310
+ /**
311
+ * @internal
312
+ */
313
+ (opts: ProcedureCallOptions<unknown>): Promise<TDef['output']>;
314
+ }
315
+ interface QueryProcedure<TDef extends BuiltProcedureDef> extends Procedure<'query', TDef> {}
316
+ interface MutationProcedure<TDef extends BuiltProcedureDef> extends Procedure<'mutation', TDef> {}
317
+ interface SubscriptionProcedure<TDef extends BuiltProcedureDef> extends Procedure<'subscription', TDef> {}
318
+ /**
319
+ * @deprecated
320
+ */
321
+ interface LegacyObservableSubscriptionProcedure<TDef extends BuiltProcedureDef> extends SubscriptionProcedure<TDef> {
322
+ _observable: true;
323
+ }
324
+ type AnyQueryProcedure = QueryProcedure<any>;
325
+ type AnyMutationProcedure = MutationProcedure<any>;
326
+ type AnySubscriptionProcedure = SubscriptionProcedure<any> | LegacyObservableSubscriptionProcedure<any>;
327
+ type AnyProcedure = AnyQueryProcedure | AnyMutationProcedure | AnySubscriptionProcedure;
328
+ type inferProcedureInput<TProcedure extends AnyProcedure> = undefined extends inferProcedureParams<TProcedure>['$types']['input'] ? void | inferProcedureParams<TProcedure>['$types']['input'] : inferProcedureParams<TProcedure>['$types']['input'];
329
+ type inferProcedureParams<TProcedure> = TProcedure extends AnyProcedure ? TProcedure['_def'] : never;
330
+ type inferProcedureOutput<TProcedure> = inferProcedureParams<TProcedure>['$types']['output'];
331
+ /**
332
+ * @internal
333
+ */
334
+ interface ErrorHandlerOptions<TContext$1> {
335
+ error: TRPCError;
336
+ type: ProcedureType | 'unknown';
337
+ path: string | undefined;
338
+ input: unknown;
339
+ ctx: TContext$1 | undefined;
340
+ }
341
+ //#endregion
342
+ //#region src/unstable-core-do-not-import/http/types.d.ts
343
+ /**
344
+ * @deprecated use `Headers` instead, this will be removed in v12
345
+ */
346
+
347
+ //#endregion
348
+ //#region src/unstable-core-do-not-import/rpc/envelopes.d.ts
349
+ /**
350
+ * Error response
351
+ */
352
+ interface TRPCErrorShape<TData extends object = object> {
353
+ code: TRPC_ERROR_CODE_NUMBER;
354
+ message: string;
355
+ data: TData;
356
+ }
357
+ /**
358
+ * JSON-RPC 2.0 Specification
359
+ */
360
+
361
+ //# sourceMappingURL=envelopes.d.ts.map
362
+ //#endregion
363
+ //#region src/unstable-core-do-not-import/transformer.d.ts
364
+ /**
365
+ * @public
366
+ */
367
+ interface DataTransformer {
368
+ serialize(object: any): any;
369
+ deserialize(object: any): any;
370
+ }
371
+ interface InputDataTransformer extends DataTransformer {
372
+ /**
373
+ * This function runs **on the client** before sending the data to the server.
374
+ */
375
+ serialize(object: any): any;
376
+ /**
377
+ * This function runs **on the server** to transform the data before it is passed to the resolver
378
+ */
379
+ deserialize(object: any): any;
380
+ }
381
+ interface OutputDataTransformer extends DataTransformer {
382
+ /**
383
+ * This function runs **on the server** before sending the data to the client.
384
+ */
385
+ serialize(object: any): any;
386
+ /**
387
+ * This function runs **only on the client** to transform the data sent from the server.
388
+ */
389
+ deserialize(object: any): any;
390
+ }
391
+ /**
392
+ * @public
393
+ */
394
+ interface CombinedDataTransformer {
395
+ /**
396
+ * Specify how the data sent from the client to the server should be transformed.
397
+ */
398
+ input: InputDataTransformer;
399
+ /**
400
+ * Specify how the data sent from the server to the client should be transformed.
401
+ */
402
+ output: OutputDataTransformer;
403
+ }
404
+ /**
405
+ * @public
406
+ */
407
+
408
+ //# sourceMappingURL=parseTRPCMessage.d.ts.map
409
+
410
+ //#endregion
411
+ //#region src/unstable-core-do-not-import/error/formatter.d.ts
412
+ /**
413
+ * @internal
414
+ */
415
+ type ErrorFormatter<TContext$1, TShape extends TRPCErrorShape> = (opts: {
416
+ error: TRPCError;
417
+ type: ProcedureType | 'unknown';
418
+ path: string | undefined;
419
+ input: unknown;
420
+ ctx: TContext$1 | undefined;
421
+ shape: DefaultErrorShape;
422
+ }) => TShape;
423
+ /**
424
+ * @internal
425
+ */
426
+ type DefaultErrorData = {
427
+ code: TRPC_ERROR_CODE_KEY;
428
+ httpStatus: number;
429
+ /**
430
+ * Path to the procedure that threw the error
431
+ */
432
+ path?: string;
433
+ /**
434
+ * Stack trace of the error (only in development)
435
+ */
436
+ stack?: string;
437
+ };
438
+ /**
439
+ * @internal
440
+ */
441
+ interface DefaultErrorShape extends TRPCErrorShape<DefaultErrorData> {
442
+ message: string;
443
+ code: TRPC_ERROR_CODE_NUMBER;
444
+ }
445
+ type Serialize$2 = (value: any) => any;
446
+ type PathArray = readonly (string | number)[];
447
+ type ProducerOnError = (opts: {
448
+ error: unknown;
449
+ path: PathArray;
450
+ }) => void;
451
+ interface JSONLProducerOptions {
452
+ serialize?: Serialize$2;
453
+ data: Record<string, unknown> | unknown[];
454
+ onError?: ProducerOnError;
455
+ formatError?: (opts: {
456
+ error: unknown;
457
+ path: PathArray;
458
+ }) => unknown;
459
+ maxDepth?: number;
460
+ /**
461
+ * Interval in milliseconds to send a ping to the client to keep the connection alive
462
+ * This will be sent as a whitespace character
463
+ * @default undefined
464
+ */
465
+ pingMs?: number;
466
+ }
467
+ /**
468
+ * JSON Lines stream producer
469
+ * @see https://jsonlines.org/
470
+ */
471
+
472
+ //# sourceMappingURL=sse.types.d.ts.map
473
+ //#endregion
474
+ //#region src/unstable-core-do-not-import/stream/sse.d.ts
475
+ type Serialize$1 = (value: any) => any;
476
+ /**
477
+ * @internal
478
+ */
479
+ interface SSEPingOptions {
480
+ /**
481
+ * Enable ping comments sent from the server
482
+ * @default false
483
+ */
484
+ enabled: boolean;
485
+ /**
486
+ * Interval in milliseconds
487
+ * @default 1000
488
+ */
489
+ intervalMs?: number;
490
+ }
491
+ interface SSEClientOptions {
492
+ /**
493
+ * Timeout and reconnect after inactivity in milliseconds
494
+ * @default undefined
495
+ */
496
+ reconnectAfterInactivityMs?: number;
497
+ }
498
+ interface SSEStreamProducerOptions<TValue$1 = unknown> {
499
+ serialize?: Serialize$1;
500
+ data: AsyncIterable<TValue$1>;
501
+ maxDepth?: number;
502
+ ping?: SSEPingOptions;
503
+ /**
504
+ * Maximum duration in milliseconds for the request before ending the stream
505
+ * @default undefined
506
+ */
507
+ maxDurationMs?: number;
508
+ /**
509
+ * End the request immediately after data is sent
510
+ * Only useful for serverless runtimes that do not support streaming responses
511
+ * @default false
512
+ */
513
+ emitAndEndImmediately?: boolean;
514
+ formatError?: (opts: {
515
+ error: unknown;
516
+ }) => unknown;
517
+ /**
518
+ * Client-specific options - these will be sent to the client as part of the first message
519
+ * @default {}
520
+ */
521
+ client?: SSEClientOptions;
522
+ }
523
+ /**
524
+ *
525
+ * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
526
+ */
527
+
528
+ //#endregion
529
+ //#region src/unstable-core-do-not-import/rootConfig.d.ts
530
+ /**
531
+ * The initial generics that are used in the init function
532
+ * @internal
533
+ */
534
+ interface RootTypes {
535
+ ctx: object;
536
+ meta: object;
537
+ errorShape: DefaultErrorShape;
538
+ transformer: boolean;
539
+ }
540
+ /**
541
+ * The default check to see if we're in a server
542
+ */
543
+
544
+ /**
545
+ * The tRPC root config
546
+ * @internal
547
+ */
548
+ interface RootConfig<TTypes extends RootTypes> {
549
+ /**
550
+ * The types that are used in the config
551
+ * @internal
552
+ */
553
+ $types: TTypes;
554
+ /**
555
+ * Use a data transformer
556
+ * @see https://trpc.io/docs/v11/data-transformers
557
+ */
558
+ transformer: CombinedDataTransformer;
559
+ /**
560
+ * Use custom error formatting
561
+ * @see https://trpc.io/docs/v11/error-formatting
562
+ */
563
+ errorFormatter: ErrorFormatter<TTypes['ctx'], TTypes['errorShape']>;
564
+ /**
565
+ * Allow `@trpc/server` to run in non-server environments
566
+ * @warning **Use with caution**, this should likely mainly be used within testing.
567
+ * @default false
568
+ */
569
+ allowOutsideOfServer: boolean;
570
+ /**
571
+ * Is this a server environment?
572
+ * @warning **Use with caution**, this should likely mainly be used within testing.
573
+ * @default typeof window === 'undefined' || 'Deno' in window || process.env.NODE_ENV === 'test'
574
+ */
575
+ isServer: boolean;
576
+ /**
577
+ * Is this development?
578
+ * Will be used to decide if the API should return stack traces
579
+ * @default process.env.NODE_ENV !== 'production'
580
+ */
581
+ isDev: boolean;
582
+ defaultMeta?: TTypes['meta'] extends object ? TTypes['meta'] : never;
583
+ /**
584
+ * Options for server-sent events (SSE) subscriptions
585
+ * @see https://trpc.io/docs/client/links/httpSubscriptionLink
586
+ */
587
+ sse?: {
588
+ /**
589
+ * Enable server-sent events (SSE) subscriptions
590
+ * @default true
591
+ */
592
+ enabled?: boolean;
593
+ } & Pick<SSEStreamProducerOptions, 'ping' | 'emitAndEndImmediately' | 'maxDurationMs' | 'client'>;
594
+ /**
595
+ * Options for batch stream
596
+ * @see https://trpc.io/docs/client/links/httpBatchStreamLink
597
+ */
598
+ jsonl?: Pick<JSONLProducerOptions, 'pingMs'>;
599
+ experimental?: {};
600
+ }
601
+ /**
602
+ * @internal
603
+ */
604
+ type CreateRootTypes<TGenerics extends RootTypes> = TGenerics;
605
+ type AnyRootTypes = CreateRootTypes<{
606
+ ctx: any;
607
+ meta: any;
608
+ errorShape: any;
609
+ transformer: any;
610
+ }>;
611
+ //#endregion
612
+ //#region src/unstable-core-do-not-import/router.d.ts
613
+ interface RouterRecord {
614
+ [key: string]: AnyProcedure | RouterRecord;
615
+ }
616
+ type DecorateProcedure<TProcedure extends AnyProcedure> = (input: inferProcedureInput<TProcedure>) => Promise<TProcedure['_def']['type'] extends 'subscription' ? TProcedure extends LegacyObservableSubscriptionProcedure<any> ? Observable<inferProcedureOutput<TProcedure>, TRPCError> : inferProcedureOutput<TProcedure> : inferProcedureOutput<TProcedure>>;
617
+ /**
618
+ * @internal
619
+ */
620
+ type DecorateRouterRecord<TRecord extends RouterRecord> = { [TKey in keyof TRecord]: TRecord[TKey] extends infer $Value ? $Value extends AnyProcedure ? DecorateProcedure<$Value> : $Value extends RouterRecord ? DecorateRouterRecord<$Value> : never : never };
621
+ /**
622
+ * @internal
623
+ */
624
+ type RouterCallerErrorHandler<TContext$1> = (opts: ErrorHandlerOptions<TContext$1>) => void;
625
+ /**
626
+ * @internal
627
+ */
628
+ type RouterCaller<TRoot extends AnyRootTypes, TRecord extends RouterRecord> = (
629
+ /**
630
+ * @note
631
+ * If passing a function, we recommend it's a cached function
632
+ * e.g. wrapped in `React.cache` to avoid unnecessary computations
633
+ */
634
+ ctx: TRoot['ctx'] | (() => MaybePromise<TRoot['ctx']>), options?: {
635
+ onError?: RouterCallerErrorHandler<TRoot['ctx']>;
636
+ signal?: AbortSignal;
637
+ }) => DecorateRouterRecord<TRecord>;
638
+ type Lazy<TAny> = (() => Promise<TAny>) & {};
639
+ type LazyLoader<TAny> = {
640
+ load: () => Promise<void>;
641
+ ref: Lazy<TAny>;
642
+ };
643
+ /**
644
+ * Lazy load a router
645
+ * @see https://trpc.io/docs/server/merging-routers#lazy-load
646
+ */
647
+
648
+ /**
649
+ * @internal
650
+ */
651
+ interface RouterDef<TRoot extends AnyRootTypes, TRecord extends RouterRecord> {
652
+ _config: RootConfig<TRoot>;
653
+ router: true;
654
+ procedure?: never;
655
+ procedures: TRecord;
656
+ record: TRecord;
657
+ lazy: Record<string, LazyLoader<AnyRouter>>;
658
+ }
659
+ interface Router<TRoot extends AnyRootTypes, TRecord extends RouterRecord> {
660
+ _def: RouterDef<TRoot, TRecord>;
661
+ /**
662
+ * @see https://trpc.io/docs/v11/server/server-side-calls
663
+ */
664
+ createCaller: RouterCaller<TRoot, TRecord>;
665
+ }
666
+ type AnyRouter = Router<any, any>;
667
+ //#endregion
73
668
  //#region src/transport.d.ts
74
669
  /**
75
670
  * Normalized representation of args passed to a transport.
@@ -77,6 +672,9 @@ declare class Store {
77
672
  type ResolvedArgsPayload = AnyRecord;
78
673
  type TransportMutations = Record<string, MutationShape>;
79
674
  type EmptyTransportMutations = Record<never, MutationShape>;
675
+ type Bivariant<Fn extends (...args: Array<any>) => any> = {
676
+ bivarianceHack: Fn;
677
+ }['bivarianceHack'];
80
678
  /**
81
679
  * Contract the fate client expects from a network transport. The transport is
82
680
  * responsible for fetching records by ID, fetching lists, and executing
@@ -105,16 +703,13 @@ type TRPCByIdResolvers<AppRouter extends AnyRouter> = Record<string, (client: TR
105
703
  /**
106
704
  * Mapping of list procedure name to a tRPC resolver factory.
107
705
  */
108
- type TRPCListResolvers<AppRouter extends AnyRouter> = Record<string, (client: TRPCClient<AppRouter>) => (input: {
109
- args?: ResolvedArgsPayload;
110
- select: Array<string>;
111
- }) => Promise<{
706
+ type TRPCListResolvers<AppRouter extends AnyRouter> = Record<string, (client: TRPCClient<AppRouter>) => Bivariant<(input: any) => Promise<{
112
707
  items: Array<{
113
708
  cursor: string | undefined;
114
709
  node: unknown;
115
710
  }>;
116
711
  pagination: Pagination;
117
- }>>;
712
+ }>>>;
118
713
  /**
119
714
  * Mapping of query procedure name to a tRPC resolver factory.
120
715
  */
@@ -181,8 +776,10 @@ declare class FateClient<Roots extends FateRoots, Mutations extends FateMutation
181
776
  private readonly parentLists;
182
777
  private readonly rootLists;
183
778
  private readonly pending;
779
+ private readonly pendingOptimisticMutations;
184
780
  private readonly optimisticMasks;
185
781
  private readonly optimisticByEntity;
782
+ private readonly optimisticEntityResolutions;
186
783
  private optimisticTokenCounter;
187
784
  private readonly requests;
188
785
  private readonly rootRequests;
@@ -215,11 +812,14 @@ declare class FateClient<Roots extends FateRoots, Mutations extends FateMutation
215
812
  }>;
216
813
  readView<T$1 extends Entity, S extends Selection<T$1>, V extends View<T$1, S>>(view: V, ref: ViewRef<T$1['__typename']>): FateThenable<ViewSnapshot<T$1, S>>;
217
814
  private mergeListState;
815
+ registerPendingOptimisticMutation(entityId: EntityId, promise: Promise<unknown>): void;
816
+ resolveOptimisticEntity(optimisticEntityId: EntityId, resolvedEntityId: EntityId): void;
218
817
  registerOptimisticUpdate(entityId: EntityId | null, select: ReadonlySet<string>): number | null;
219
818
  clearOptimisticUpdate(token: number | null): void;
220
819
  getPendingOptimisticMask(entityId: EntityId | null, options?: {
221
820
  excludeToken?: number | null;
222
821
  }): FieldMask | null;
822
+ private getPendingOptimisticMutations;
223
823
  filterSelectionForPendingOptimistics(entityId: EntityId | null, select: Set<string>, options?: {
224
824
  excludeToken?: number | null;
225
825
  }): Set<string>;
@@ -230,13 +830,13 @@ declare class FateClient<Roots extends FateRoots, Mutations extends FateMutation
230
830
  ids: ReadonlyArray<EntityId>;
231
831
  pagination?: Pagination;
232
832
  }> | undefined>;
233
- request<R$1 extends Request>(request: R$1, options?: RequestOptions): Promise<RequestResult<Roots, R$1>>;
234
- releaseRequest(request: Request, mode: RequestMode): void;
833
+ request<R$1 extends Request$1>(request: R$1, options?: RequestOptions): Promise<RequestResult<Roots, R$1>>;
834
+ releaseRequest(request: Request$1, mode: RequestMode): void;
235
835
  private handleStoreAndNetworkRequest;
236
836
  private getRootType;
237
837
  private executeRequest;
238
838
  private hasRequestData;
239
- getRequestResult<R$1 extends Request>(request: R$1): RequestResult<Roots, R$1>;
839
+ getRequestResult<R$1 extends Request$1>(request: R$1): RequestResult<Roots, R$1>;
240
840
  private fetchByIdAndNormalize;
241
841
  private fetchQueryAndNormalize;
242
842
  private fetchListAndNormalize;
@@ -523,7 +1123,7 @@ type NodesItem<V extends View<any, any>> = Readonly<{
523
1123
  }>;
524
1124
  type RequestItem = ListItem<View<any, any>> | NodeItem<View<any, any>> | NodesItem<View<any, any>> | QueryItem<View<any, any>>;
525
1125
  /** Collection of node and list requests describing the data a screen needs. */
526
- type Request = Record<string, RequestItem>;
1126
+ type Request$1 = Record<string, RequestItem>;
527
1127
  type AnyView = View<any, any>;
528
1128
  type AnyListItem = ListItem<AnyView>;
529
1129
  type AnyQueryItem = QueryItem<AnyView>;
@@ -540,7 +1140,7 @@ type ConnectionNodeType<Root> = Root extends {
540
1140
  node?: infer Node;
541
1141
  };
542
1142
  } ? ViewEntityName<Node & View<any, any>> : never;
543
- type ListResult<Item extends AnyRequestItem, Type extends TypeName, Result> = Item extends AnyNodeItem ? ViewRef<Type> : Item extends AnyNodesItem ? Array<ViewRef<Type>> : Item extends AnyQueryItem ? Result extends null ? ViewRef<Type> | null : ViewRef<Type> : Item extends AnyListItem ? Item['list'] extends {
1143
+ type ListResult<Item extends AnyRequestItem, Type extends TypeName, Result$1> = Item extends AnyNodeItem ? ViewRef<Type> : Item extends AnyNodesItem ? Array<ViewRef<Type>> : Item extends AnyQueryItem ? Result$1 extends null ? ViewRef<Type> | null : ViewRef<Type> : Item extends AnyListItem ? Item['list'] extends {
544
1144
  items?: {
545
1145
  node?: View<any, any>;
546
1146
  };
@@ -561,10 +1161,10 @@ declare const RootKind = "__fate__root";
561
1161
  /** Brand used on mutation definitions to mark their identity in the d.ts output. */
562
1162
  declare const MutationKind = "__fate__mutation";
563
1163
  /** Metadata describing a root query for a particular entity and result shape. */
564
- type RootDefinition<Type extends TypeName, Result> = Readonly<{
1164
+ type RootDefinition<Type extends TypeName, Result$1> = Readonly<{
565
1165
  [RootKind]: true;
566
1166
  type: Type;
567
- }> & __RootResultAnchor<Result> & __RootTypeAnchor<Type>;
1167
+ }> & __RootResultAnchor<Result$1> & __RootTypeAnchor<Type>;
568
1168
  /** Minimal root description used for typing root maps. */
569
1169
  type FateRoots = Record<string, RootDefinition<TypeName, unknown>>;
570
1170
  /** Extracts the entity type name from a root definition. */
@@ -612,4 +1212,4 @@ interface FateThenable<T$1> extends PromiseLike<T$1> {
612
1212
  value: T$1;
613
1213
  }
614
1214
  //#endregion
615
- export { ViewSelection as A, RequestOptions as B, TypeConfig as C, ViewEntity as D, ViewData as E, isViewTag as F, Transport as H, FateMutations as I, mutation as L, ViewTag as M, __FateEntityBrand as N, ViewEntityName as O, __FateSelectionBrand as P, FateClient as R, Snapshot as S, View as T, createTRPCTransport as U, createClient as V, getSelectionPlan as W, Pagination as _, Entity as a, RootDefinition as b, FateThenable as c, MutationDefinition as d, MutationEntity as f, NodesItem as g, MutationResult as h, ConnectionTag as i, ViewSnapshot as j, ViewRef as k, ListItem as l, MutationInput as m, ConnectionMetadata as n, EntityId as o, MutationIdentifier as p, ConnectionRef as r, FateRoots as s, AnyRecord as t, Mask as u, Request as v, TypeName as w, Selection as x, RequestResult as y, RequestMode as z };
1215
+ export { ViewSelection as A, RequestOptions as B, TypeConfig as C, ViewEntity as D, ViewData as E, isViewTag as F, getSelectionPlan as G, Transport as H, FateMutations as I, mutation as L, ViewTag as M, __FateEntityBrand as N, ViewEntityName as O, __FateSelectionBrand as P, FateClient as R, Snapshot as S, View as T, createTRPCTransport as U, createClient as V, QueryProcedure as W, Pagination as _, Entity as a, RootDefinition as b, FateThenable as c, MutationDefinition as d, MutationEntity as f, NodesItem as g, MutationResult as h, ConnectionTag as i, ViewSnapshot as j, ViewRef as k, ListItem as l, MutationInput as m, ConnectionMetadata as n, EntityId as o, MutationIdentifier as p, ConnectionRef as r, FateRoots as s, AnyRecord as t, Mask as u, Request$1 as v, TypeName as w, Selection as x, RequestResult as y, RequestMode as z };
package/package.json CHANGED
@@ -1,47 +1,50 @@
1
1
  {
2
2
  "name": "@nkzw/fate",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "fate is a modern data client for React.",
5
5
  "homepage": "https://github.com/nkzw-tech/fate",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/nkzw-tech/fate"
9
- },
10
6
  "license": "MIT",
11
7
  "author": {
12
8
  "name": "Christoph Nakazawa",
13
9
  "email": "christoph.pojer@gmail.com"
14
10
  },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/nkzw-tech/fate"
14
+ },
15
+ "bin": {
16
+ "fate": "./lib/cli.mjs"
17
+ },
18
+ "files": [
19
+ "lib"
20
+ ],
15
21
  "type": "module",
22
+ "main": "./lib/index.mjs",
23
+ "types": "./lib/index.d.mts",
16
24
  "exports": {
17
25
  ".": {
18
26
  "types": "./lib/index.d.mts",
27
+ "@nkzw/source": "./src/index.ts",
19
28
  "default": "./lib/index.mjs"
20
29
  },
21
30
  "./cli": {
22
31
  "types": "./lib/cli.d.mts",
32
+ "@nkzw/source": "./src/cli.ts",
23
33
  "default": "./lib/cli.mjs"
24
34
  },
25
35
  "./server": {
26
36
  "types": "./lib/server.d.mts",
37
+ "@nkzw/source": "./src/server.ts",
27
38
  "default": "./lib/server.mjs"
28
39
  }
29
40
  },
30
- "main": "./lib/index.mjs",
31
- "types": "./lib/index.d.mts",
32
- "bin": {
33
- "fate": "./lib/cli.mjs"
34
- },
35
- "files": [
36
- "lib"
37
- ],
38
41
  "dependencies": {
39
42
  "superjson": "^2.2.6",
40
- "zod": "^4.1.13"
43
+ "zod": "^4.3.5"
41
44
  },
42
45
  "devDependencies": {
43
- "@trpc/client": "^11.7.2",
44
- "@trpc/server": "^11.7.2"
46
+ "@trpc/client": "^11.8.1",
47
+ "@trpc/server": "^11.8.1"
45
48
  },
46
49
  "peerDependencies": {
47
50
  "@trpc/client": "^11.6.0"