@nkzw/fate 0.1.2 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +810 -129
  2. package/docs/api/classes/FateClient.md +832 -0
  3. package/docs/api/functions/clientRoot.md +27 -0
  4. package/docs/api/functions/createClient.md +21 -0
  5. package/docs/api/functions/createHTTPTransport.md +51 -0
  6. package/docs/api/functions/createTRPCTransport.md +46 -0
  7. package/docs/api/functions/getListEntries.md +15 -0
  8. package/docs/api/functions/getSelectionPlan.md +36 -0
  9. package/docs/api/functions/isRecord.md +15 -0
  10. package/docs/api/functions/isViewTag.md +17 -0
  11. package/docs/api/functions/liveConnectionTopic.md +19 -0
  12. package/docs/api/functions/liveEntityTopic.md +19 -0
  13. package/docs/api/functions/liveGlobalConnectionTopic.md +15 -0
  14. package/docs/api/functions/mutation.md +32 -0
  15. package/docs/api/functions/toEntityId.md +21 -0
  16. package/docs/api/functions/view.md +26 -0
  17. package/docs/api/index.md +81 -0
  18. package/docs/api/interfaces/FateThenable.md +31 -0
  19. package/docs/api/interfaces/Transport.md +199 -0
  20. package/docs/api/server/classes/FateRequestError.md +67 -0
  21. package/docs/api/server/drizzle/functions/createDrizzleFate.md +431 -0
  22. package/docs/api/server/drizzle/functions/createDrizzleSourceAdapter.md +21 -0
  23. package/docs/api/server/drizzle/functions/createDrizzleSourceRegistry.md +21 -0
  24. package/docs/api/server/drizzle/index.md +23 -0
  25. package/docs/api/server/drizzle/type-aliases/DrizzleManyToManyConfig.md +15 -0
  26. package/docs/api/server/drizzle/type-aliases/DrizzleManyToManyInput.md +5 -0
  27. package/docs/api/server/drizzle/type-aliases/DrizzleQueryExtra.md +21 -0
  28. package/docs/api/server/drizzle/type-aliases/DrizzleSourceAdapter.md +337 -0
  29. package/docs/api/server/drizzle/type-aliases/DrizzleViewConfig.md +29 -0
  30. package/docs/api/server/functions/bindSourceProcedures.md +32 -0
  31. package/docs/api/server/functions/computed.md +43 -0
  32. package/docs/api/server/functions/count.md +21 -0
  33. package/docs/api/server/functions/createFateFetchHandler.md +21 -0
  34. package/docs/api/server/functions/createFateServer.md +41 -0
  35. package/docs/api/server/functions/createHonoFateHandler.md +21 -0
  36. package/docs/api/server/functions/createLiveEventBus.md +17 -0
  37. package/docs/api/server/functions/createNestedSourcePlan.md +103 -0
  38. package/docs/api/server/functions/createResolver.md +74 -0
  39. package/docs/api/server/functions/createSourcePlan.md +95 -0
  40. package/docs/api/server/functions/createSourceProcedures.md +46 -0
  41. package/docs/api/server/functions/dataView.md +32 -0
  42. package/docs/api/server/functions/field.md +15 -0
  43. package/docs/api/server/functions/getNestedSelection.md +19 -0
  44. package/docs/api/server/functions/getScopedArgs.md +21 -0
  45. package/docs/api/server/functions/hasNestedSelection.md +19 -0
  46. package/docs/api/server/functions/list.md +28 -0
  47. package/docs/api/server/functions/refetchSourceById.md +55 -0
  48. package/docs/api/server/functions/resolveSourceById.md +55 -0
  49. package/docs/api/server/functions/resolveSourceByIds.md +55 -0
  50. package/docs/api/server/functions/resolveSourceConnection.md +67 -0
  51. package/docs/api/server/functions/resolver.md +42 -0
  52. package/docs/api/server/functions/toPrismaSelect.md +25 -0
  53. package/docs/api/server/functions/withConnection.md +24 -0
  54. package/docs/api/server/index.md +109 -0
  55. package/docs/api/server/prisma/functions/createPrismaFate.md +435 -0
  56. package/docs/api/server/prisma/functions/createPrismaSourceAdapter.md +21 -0
  57. package/docs/api/server/prisma/functions/createPrismaSourceRegistry.md +21 -0
  58. package/docs/api/server/prisma/functions/prismaConnectionArgs.md +57 -0
  59. package/docs/api/server/prisma/index.md +23 -0
  60. package/docs/api/server/prisma/type-aliases/PrismaDelegate.md +59 -0
  61. package/docs/api/server/prisma/type-aliases/PrismaQueryExtra.md +5 -0
  62. package/docs/api/server/prisma/type-aliases/PrismaSourceAdapter.md +343 -0
  63. package/docs/api/server/prisma/type-aliases/PrismaViewConfig.md +31 -0
  64. package/docs/api/server/type-aliases/ComputedField.md +55 -0
  65. package/docs/api/server/type-aliases/ComputedSelection.md +5 -0
  66. package/docs/api/server/type-aliases/ConnectionItem.md +29 -0
  67. package/docs/api/server/type-aliases/ConnectionPagination.md +39 -0
  68. package/docs/api/server/type-aliases/ConnectionResult.md +29 -0
  69. package/docs/api/server/type-aliases/CountSelection.md +29 -0
  70. package/docs/api/server/type-aliases/CountWhere.md +5 -0
  71. package/docs/api/server/type-aliases/DataViewListOptions.md +13 -0
  72. package/docs/api/server/type-aliases/DataViewOrderBy.md +5 -0
  73. package/docs/api/server/type-aliases/DataViewOrderDirection.md +5 -0
  74. package/docs/api/server/type-aliases/DataViewResult.md +11 -0
  75. package/docs/api/server/type-aliases/Entity.md +21 -0
  76. package/docs/api/server/type-aliases/FateServer.md +75 -0
  77. package/docs/api/server/type-aliases/FateServerManifest.md +5 -0
  78. package/docs/api/server/type-aliases/FieldSelection.md +21 -0
  79. package/docs/api/server/type-aliases/LiveConnectionEventType.md +5 -0
  80. package/docs/api/server/type-aliases/LiveConnectionSourceEvent.md +5 -0
  81. package/docs/api/server/type-aliases/LiveEventBus.md +5 -0
  82. package/docs/api/server/type-aliases/LiveEventType.md +5 -0
  83. package/docs/api/server/type-aliases/LiveSourceEvent.md +5 -0
  84. package/docs/api/server/type-aliases/NativeFateAPI.md +47 -0
  85. package/docs/api/server/type-aliases/OrderDirection.md +5 -0
  86. package/docs/api/server/type-aliases/SourceConfig.md +55 -0
  87. package/docs/api/server/type-aliases/SourceDefinition.md +55 -0
  88. package/docs/api/server/type-aliases/SourceOrder.md +5 -0
  89. package/docs/api/server/type-aliases/SourceOrderField.md +21 -0
  90. package/docs/api/server/type-aliases/SourcePlan.md +29 -0
  91. package/docs/api/server/type-aliases/SourcePlanNode.md +29 -0
  92. package/docs/api/server/type-aliases/SourceRegistry.md +11 -0
  93. package/docs/api/server/type-aliases/SourceRelation.md +15 -0
  94. package/docs/api/server/type-aliases/SourceRelationConfig.md +23 -0
  95. package/docs/api/server/variables/byIdInput.md +5 -0
  96. package/docs/api/server/variables/connectionArgs.md +7 -0
  97. package/docs/api/type-aliases/ConnectionMetadata.md +7 -0
  98. package/docs/api/type-aliases/ConnectionRef.md +13 -0
  99. package/docs/api/type-aliases/Entity.md +15 -0
  100. package/docs/api/type-aliases/EntityId.md +7 -0
  101. package/docs/api/type-aliases/FateLiveConnectionEvent.md +5 -0
  102. package/docs/api/type-aliases/FateLiveEvent.md +5 -0
  103. package/docs/api/type-aliases/FateMutations.md +7 -0
  104. package/docs/api/type-aliases/FateOperation.md +5 -0
  105. package/docs/api/type-aliases/FateProtocolRequest.md +5 -0
  106. package/docs/api/type-aliases/FateProtocolResponse.md +5 -0
  107. package/docs/api/type-aliases/FateRecord.md +7 -0
  108. package/docs/api/type-aliases/FateRoots.md +7 -0
  109. package/docs/api/type-aliases/InferFateAPI.md +11 -0
  110. package/docs/api/type-aliases/List.md +5 -0
  111. package/docs/api/type-aliases/ListEntry.md +5 -0
  112. package/docs/api/type-aliases/ListItem.md +13 -0
  113. package/docs/api/type-aliases/Mask.md +15 -0
  114. package/docs/api/type-aliases/MutationDefinition.md +21 -0
  115. package/docs/api/type-aliases/MutationEntity.md +13 -0
  116. package/docs/api/type-aliases/MutationIdentifier.md +19 -0
  117. package/docs/api/type-aliases/MutationInput.md +13 -0
  118. package/docs/api/type-aliases/MutationResult.md +13 -0
  119. package/docs/api/type-aliases/NodesItem.md +13 -0
  120. package/docs/api/type-aliases/Pagination.md +39 -0
  121. package/docs/api/type-aliases/Request.md +7 -0
  122. package/docs/api/type-aliases/RequestMode.md +7 -0
  123. package/docs/api/type-aliases/RequestOptions.md +7 -0
  124. package/docs/api/type-aliases/RequestResult.md +18 -0
  125. package/docs/api/type-aliases/Selection.md +13 -0
  126. package/docs/api/type-aliases/Snapshot.md +7 -0
  127. package/docs/api/type-aliases/TypeConfig.md +41 -0
  128. package/docs/api/type-aliases/View.md +17 -0
  129. package/docs/api/type-aliases/ViewData.md +18 -0
  130. package/docs/api/type-aliases/ViewEntity.md +13 -0
  131. package/docs/api/type-aliases/ViewEntityName.md +13 -0
  132. package/docs/api/type-aliases/ViewRef.md +13 -0
  133. package/docs/api/type-aliases/ViewSelection.md +13 -0
  134. package/docs/api/type-aliases/ViewSnapshot.md +18 -0
  135. package/docs/api/type-aliases/ViewTag.md +7 -0
  136. package/docs/api/variables/ConnectionTag.md +7 -0
  137. package/docs/guide/actions.md +263 -0
  138. package/docs/guide/core-concepts.md +22 -0
  139. package/docs/guide/getting-started.md +57 -0
  140. package/docs/guide/list-views.md +86 -0
  141. package/docs/guide/live-views.md +245 -0
  142. package/docs/guide/requests.md +130 -0
  143. package/docs/guide/server-integration.md +630 -0
  144. package/docs/guide/views.md +278 -0
  145. package/docs/guide/void-integration.md +167 -0
  146. package/docs/index.md +4 -0
  147. package/lib/cli.mjs +17 -250
  148. package/lib/clientStub.d.mts +6 -0
  149. package/lib/clientStub.mjs +6 -0
  150. package/lib/executor-BqwHdN3n.d.mts +468 -0
  151. package/lib/index.d.mts +64 -3
  152. package/lib/index.mjs +1965 -559
  153. package/lib/list-4wRNSVgI.d.mts +10 -0
  154. package/lib/list-C_mi6GnE.mjs +16 -0
  155. package/lib/list.d.mts +2 -0
  156. package/lib/list.mjs +2 -0
  157. package/lib/liveTopics-DzNtJaBD.mjs +197 -0
  158. package/lib/{record-DnhZuvUe.mjs → record-AeZJC9fd.mjs} +1 -2
  159. package/lib/record-ENh92gyb.d.mts +315 -0
  160. package/lib/server/drizzle.d.mts +304 -0
  161. package/lib/server/drizzle.mjs +688 -0
  162. package/lib/server/prisma.d.mts +309 -0
  163. package/lib/server/prisma.mjs +345 -0
  164. package/lib/server.d.mts +82 -184
  165. package/lib/server.mjs +870 -416
  166. package/lib/sourceRouter-Bwpkr062.mjs +972 -0
  167. package/lib/{types-Djlh7mMH.d.mts → types-Dz46PXr3.d.mts} +327 -197
  168. package/lib/vite.d.mts +17 -0
  169. package/lib/vite.mjs +592 -0
  170. package/package.json +44 -6
@@ -0,0 +1,309 @@
1
+ import { q as QueryProcedure, t as AnyRecord } from "../types-Dz46PXr3.mjs";
2
+ import { S as ConnectionResult, c as SourceConfig, f as SourcePlan, k as DataView, l as SourceDefinition, o as DataViewModule, p as SourcePlanNode, s as OrderDirection, t as SourceRegistry } from "../executor-BqwHdN3n.mjs";
3
+ import * as _$zod from "zod";
4
+ import * as _$zod_v4_core0 from "zod/v4/core";
5
+
6
+ //#region src/server/prisma.d.ts
7
+ type PrismaDelegate = {
8
+ findMany?: (args: any) => Promise<Array<AnyRecord>>;
9
+ findUnique?: (args: any) => Promise<AnyRecord | null>;
10
+ groupBy?: (args: any) => Promise<Array<AnyRecord>>;
11
+ };
12
+ type PrismaQueryExtra = AnyRecord;
13
+ type PrismaViewConfig<Context, Item extends AnyRecord = AnyRecord> = {
14
+ delegate: (ctx: Context) => unknown;
15
+ } & SourceConfig<Item, unknown>;
16
+ type PrismaViewsInput<Context> = Array<DataView<AnyRecord> | PrismaViewConfig<Context, AnyRecord>> | DataViewModule;
17
+ type PrismaSourceAdapterOptions<Context> = {
18
+ prisma?: (ctx: Context) => unknown;
19
+ views: PrismaViewsInput<Context>;
20
+ };
21
+ type SourceTarget<Item extends AnyRecord = AnyRecord> = DataView<Item> | SourceDefinition<Item, unknown>;
22
+ type ViewTarget<Item extends AnyRecord = AnyRecord> = DataView<Item>;
23
+ type ListConfig = {
24
+ defaultSize?: number;
25
+ };
26
+ type ViewProcedureInput<Item extends AnyRecord, ById extends boolean | undefined, List extends boolean | ListConfig | undefined> = ViewTarget<Item> | {
27
+ byId?: ById;
28
+ list?: List;
29
+ view: ViewTarget<Item>;
30
+ };
31
+ type PrismaSourceAdapter<Context> = {
32
+ fetchById: <Item extends AnyRecord = AnyRecord>({
33
+ ctx,
34
+ extra,
35
+ id,
36
+ plan
37
+ }: {
38
+ ctx: Context;
39
+ extra?: PrismaQueryExtra;
40
+ id: string;
41
+ plan: SourcePlan<Item, Context>;
42
+ }) => Promise<Item | null>;
43
+ fetchByIds: <Item extends AnyRecord = AnyRecord>({
44
+ ctx,
45
+ extra,
46
+ ids,
47
+ plan
48
+ }: {
49
+ ctx: Context;
50
+ extra?: PrismaQueryExtra;
51
+ ids: Array<string>;
52
+ plan: SourcePlan<Item, Context>;
53
+ }) => Promise<Array<Item>>;
54
+ fetchConnection: <Item extends AnyRecord = AnyRecord>({
55
+ ctx,
56
+ cursor,
57
+ direction,
58
+ extra,
59
+ plan,
60
+ skip,
61
+ take
62
+ }: {
63
+ ctx: Context;
64
+ cursor?: string;
65
+ direction: 'backward' | 'forward';
66
+ extra?: PrismaQueryExtra;
67
+ plan: SourcePlan<Item, Context>;
68
+ skip?: number;
69
+ take: number;
70
+ }) => Promise<Array<Item>>;
71
+ getSource: <Item extends AnyRecord = AnyRecord>(target: SourceTarget<Item>) => SourceDefinition<Item, unknown>;
72
+ registry: SourceRegistry<Context>;
73
+ resolveById: <Item extends AnyRecord = AnyRecord>(options: {
74
+ ctx: Context;
75
+ extra?: PrismaQueryExtra;
76
+ id: string;
77
+ input: SourceInput;
78
+ view: ViewTarget<Item>;
79
+ }) => Promise<AnyRecord | null>;
80
+ resolveByIds: <Item extends AnyRecord = AnyRecord>(options: {
81
+ ctx: Context;
82
+ extra?: PrismaQueryExtra;
83
+ ids: Array<string>;
84
+ input: SourceInput;
85
+ view: ViewTarget<Item>;
86
+ }) => Promise<Array<AnyRecord>>;
87
+ resolveConnection: <Item extends AnyRecord = AnyRecord>(options: {
88
+ ctx: Context;
89
+ cursor?: string;
90
+ direction: 'backward' | 'forward';
91
+ extra?: PrismaQueryExtra;
92
+ input: SourceInput;
93
+ skip?: number;
94
+ take: number;
95
+ view: ViewTarget<Item>;
96
+ }) => Promise<Array<AnyRecord>>;
97
+ };
98
+ type ProcedureLike = {
99
+ input: (schema: any) => {
100
+ query: (resolver: (options: any) => unknown) => any;
101
+ };
102
+ };
103
+ type SourceInput = {
104
+ args?: Record<string, unknown>;
105
+ select: Iterable<string>;
106
+ };
107
+ declare const prismaConnectionArgs: ({
108
+ cursor,
109
+ direction,
110
+ node,
111
+ skip,
112
+ take
113
+ }: {
114
+ cursor?: string;
115
+ direction: "backward" | "forward";
116
+ node: SourcePlanNode<any, any>;
117
+ skip?: number;
118
+ take: number;
119
+ }) => {
120
+ orderBy: {
121
+ [x: string]: OrderDirection;
122
+ }[];
123
+ take: number;
124
+ cursor?: {
125
+ id: string;
126
+ } | undefined;
127
+ skip?: number | undefined;
128
+ };
129
+ declare function createPrismaSourceAdapter<Context>({
130
+ prisma,
131
+ views
132
+ }: PrismaSourceAdapterOptions<Context>): PrismaSourceAdapter<Context>;
133
+ declare const createPrismaSourceRegistry: <Context>(options: Parameters<typeof createPrismaSourceAdapter<Context>>[0]) => SourceRegistry<Context>;
134
+ declare function createPrismaFate<Context, Procedure extends ProcedureLike>({
135
+ procedure,
136
+ ...options
137
+ }: Parameters<typeof createPrismaSourceAdapter<Context>>[0] & {
138
+ procedure: Procedure;
139
+ }): {
140
+ connection: <TItem, TNode = TItem, TAdditionalInput extends _$zod.ZodObject<Record<string, _$zod.ZodType<unknown, unknown, _$zod_v4_core0.$ZodTypeInternals<unknown, unknown>>>, _$zod_v4_core0.$strip> | undefined = undefined>(options: {
141
+ defaultSize?: number;
142
+ getCursor?: ((node: TNode) => string) | undefined;
143
+ input?: TAdditionalInput | undefined;
144
+ map?: ((options: {
145
+ ctx: Procedure extends {
146
+ input: (schema: any) => {
147
+ query: (resolver: (options: {
148
+ ctx: infer TContext;
149
+ }) => unknown) => unknown;
150
+ };
151
+ } ? TContext : unknown;
152
+ input: {
153
+ select: string[];
154
+ args?: Record<string, unknown> | undefined;
155
+ } & {
156
+ args?: ((Record<string, unknown> | undefined) & (TAdditionalInput extends _$zod.ZodObject<Record<string, _$zod.ZodType<unknown, unknown, _$zod_v4_core0.$ZodTypeInternals<unknown, unknown>>>, _$zod_v4_core0.$strip> ? _$zod.infer<TAdditionalInput> : object)) | undefined;
157
+ };
158
+ items: TItem[];
159
+ }) => TNode[] | Promise<TNode[]>) | undefined;
160
+ query: (options: {
161
+ ctx: Procedure extends {
162
+ input: (schema: any) => {
163
+ query: (resolver: (options: {
164
+ ctx: infer TContext;
165
+ }) => unknown) => unknown;
166
+ };
167
+ } ? TContext : unknown;
168
+ cursor?: string;
169
+ direction: "forward" | "backward";
170
+ input: {
171
+ select: string[];
172
+ args?: Record<string, unknown> | undefined;
173
+ } & {
174
+ args?: ((Record<string, unknown> | undefined) & (TAdditionalInput extends _$zod.ZodObject<Record<string, _$zod.ZodType<unknown, unknown, _$zod_v4_core0.$ZodTypeInternals<unknown, unknown>>>, _$zod_v4_core0.$strip> ? _$zod.infer<TAdditionalInput> : object)) | undefined;
175
+ };
176
+ skip?: number;
177
+ take: number;
178
+ }) => Promise<TItem[]>;
179
+ }) => QueryProcedure<{
180
+ input: {
181
+ select: string[];
182
+ args?: Record<string, unknown> | undefined;
183
+ } & {
184
+ args?: ((Record<string, unknown> | undefined) & (TAdditionalInput extends _$zod.ZodObject<Record<string, _$zod.ZodType<unknown, unknown, _$zod_v4_core0.$ZodTypeInternals<unknown, unknown>>>, _$zod_v4_core0.$strip> ? _$zod.infer<TAdditionalInput> : object)) | undefined;
185
+ };
186
+ meta: unknown;
187
+ output: ConnectionResult<TNode>;
188
+ }>;
189
+ createPlan: <Item extends AnyRecord = AnyRecord>({
190
+ args,
191
+ ctx,
192
+ select,
193
+ view
194
+ }: SourceInput & {
195
+ ctx?: Context;
196
+ view: ViewTarget<Item>;
197
+ }) => {
198
+ root: SourcePlanNode<unknown, unknown>;
199
+ source: SourceDefinition<Item, unknown>;
200
+ args: AnyRecord | undefined;
201
+ ctx: Context | undefined;
202
+ resolve: (item: Item) => Promise<AnyRecord>;
203
+ resolveMany: (items: Array<AnyRecord>) => Promise<Array<AnyRecord>>;
204
+ selectedPaths: Set<string>;
205
+ view: DataView<Item>;
206
+ };
207
+ procedures: <Item extends AnyRecord, ById extends boolean | undefined = undefined, List extends boolean | ListConfig | undefined = undefined>(input: ViewProcedureInput<Item, ById, List>) => (ById extends false ? Record<never, never> : {
208
+ byId: ReturnType<ReturnType<Procedure["input"]>["query"]>;
209
+ }) & (List extends false ? Record<never, never> : {
210
+ list: QueryProcedure<{
211
+ input: {
212
+ select: string[];
213
+ args?: Record<string, unknown> | undefined;
214
+ } & {
215
+ args?: Record<string, unknown> | (Record<string, unknown> & object) | undefined;
216
+ };
217
+ meta: unknown;
218
+ output: ConnectionResult<unknown>;
219
+ }>;
220
+ });
221
+ resolveById: <Item extends AnyRecord = AnyRecord>({
222
+ ctx,
223
+ extra,
224
+ id,
225
+ input,
226
+ view
227
+ }: {
228
+ ctx: Context;
229
+ extra?: PrismaQueryExtra;
230
+ id: string;
231
+ input: SourceInput;
232
+ view: ViewTarget<Item>;
233
+ }) => Promise<AnyRecord | null>;
234
+ resolveByIds: <Item extends AnyRecord = AnyRecord>({
235
+ ctx,
236
+ extra,
237
+ ids,
238
+ input,
239
+ view
240
+ }: {
241
+ ctx: Context;
242
+ extra?: PrismaQueryExtra;
243
+ ids: Array<string>;
244
+ input: SourceInput;
245
+ view: ViewTarget<Item>;
246
+ }) => Promise<AnyRecord[]>;
247
+ resolveConnection: <Item extends AnyRecord = AnyRecord>({
248
+ ctx,
249
+ cursor,
250
+ direction,
251
+ extra,
252
+ input,
253
+ skip,
254
+ take,
255
+ view
256
+ }: {
257
+ ctx: Context;
258
+ cursor?: string;
259
+ direction: "backward" | "forward";
260
+ extra?: PrismaQueryExtra;
261
+ input: SourceInput;
262
+ skip?: number;
263
+ take: number;
264
+ view: ViewTarget<Item>;
265
+ }) => Promise<AnyRecord[]>;
266
+ fetchById: <Item extends AnyRecord = AnyRecord>({
267
+ ctx,
268
+ extra,
269
+ id,
270
+ plan
271
+ }: {
272
+ ctx: Context;
273
+ extra?: PrismaQueryExtra;
274
+ id: string;
275
+ plan: SourcePlan<Item, Context>;
276
+ }) => Promise<Item | null>;
277
+ fetchByIds: <Item extends AnyRecord = AnyRecord>({
278
+ ctx,
279
+ extra,
280
+ ids,
281
+ plan
282
+ }: {
283
+ ctx: Context;
284
+ extra?: PrismaQueryExtra;
285
+ ids: Array<string>;
286
+ plan: SourcePlan<Item, Context>;
287
+ }) => Promise<Item[]>;
288
+ fetchConnection: <Item extends AnyRecord = AnyRecord>({
289
+ ctx,
290
+ cursor,
291
+ direction,
292
+ extra,
293
+ plan,
294
+ skip,
295
+ take
296
+ }: {
297
+ ctx: Context;
298
+ cursor?: string;
299
+ direction: "backward" | "forward";
300
+ extra?: PrismaQueryExtra;
301
+ plan: SourcePlan<Item, Context>;
302
+ skip?: number;
303
+ take: number;
304
+ }) => Promise<Item[]>;
305
+ getSource: <Item extends AnyRecord = AnyRecord>(target: SourceTarget<Item>) => SourceDefinition<Item, unknown>;
306
+ registry: SourceRegistry<Context>;
307
+ };
308
+ //#endregion
309
+ export { PrismaDelegate, PrismaQueryExtra, PrismaSourceAdapter, PrismaViewConfig, createPrismaFate, createPrismaSourceAdapter, createPrismaSourceRegistry, prismaConnectionArgs };
@@ -0,0 +1,345 @@
1
+ import { t as isRecord } from "../record-AeZJC9fd.mjs";
2
+ import { O as withConnection, S as isDataView, T as toPrismaSelect, c as resolveSourceConnection, d as createSourceDefinitions, f as createSourcePlan, g as attachComputedState, i as createSourceRegistry, l as collectDataViewConfigs, o as resolveSourceById, p as getDataViewSourceConfig, s as resolveSourceByIds, t as bindSourceProcedures } from "../sourceRouter-Bwpkr062.mjs";
3
+ //#region src/server/prisma.ts
4
+ /**
5
+ * Fate's Prisma integration.
6
+ *
7
+ * @example
8
+ * import { createPrismaFate } from '@nkzw/fate/server/prisma';
9
+ *
10
+ * @module @nkzw/fate/server/prisma
11
+ */
12
+ const lowerFirst = (value) => `${value.slice(0, 1).toLowerCase()}${value.slice(1)}`;
13
+ const isPrismaViewConfig = (value) => isRecord(value) && isDataView(value.view) && typeof value.delegate === "function";
14
+ const getPrismaClient = ({ ctx, prisma }) => {
15
+ if (prisma) return prisma(ctx);
16
+ return isRecord(ctx) && isRecord(ctx.prisma) ? ctx.prisma : ctx;
17
+ };
18
+ const createPrismaDelegate = (view, prisma) => {
19
+ const delegateName = lowerFirst(view.typeName);
20
+ return (ctx) => {
21
+ const client = getPrismaClient({
22
+ ctx,
23
+ prisma
24
+ });
25
+ if (!isRecord(client)) throw new Error(`Prisma client for ${view.typeName} could not be inferred. Pass 'prisma' to createPrismaFate.`);
26
+ const delegate = client[delegateName];
27
+ if (!delegate) throw new Error(`Prisma delegate '${delegateName}' for ${view.typeName} was not found.`);
28
+ return delegate;
29
+ };
30
+ };
31
+ const createPrismaViewConfigs = ({ prisma, views }) => Array.isArray(views) ? views.map((view) => {
32
+ if (isPrismaViewConfig(view)) return view;
33
+ if (!isDataView(view)) throw new Error(`Expected a data view or Prisma view config.`);
34
+ const config = getDataViewSourceConfig(view);
35
+ return {
36
+ ...config,
37
+ delegate: createPrismaDelegate(config.view, prisma)
38
+ };
39
+ }) : collectDataViewConfigs(views).map((config) => ({
40
+ ...config,
41
+ delegate: createPrismaDelegate(config.view, prisma)
42
+ }));
43
+ const inferPrismaRelation = ({ field, kind, source, target }) => {
44
+ if (kind === "one") return {
45
+ foreignKey: target.id,
46
+ localKey: `${field}Id`
47
+ };
48
+ return {
49
+ foreignKey: `${lowerFirst(source.view.typeName)}Id`,
50
+ localKey: source.id
51
+ };
52
+ };
53
+ const stableStringify = (value) => {
54
+ if (Array.isArray(value)) return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
55
+ if (isRecord(value)) return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => `${JSON.stringify(key)}:${stableStringify(entry)}`).join(",")}}`;
56
+ return JSON.stringify(value);
57
+ };
58
+ const resolveSourceReference = (source) => typeof source === "function" ? source() : source;
59
+ const isSourceDefinition = (target) => "view" in target && "id" in target;
60
+ const toPrismaOrderBy = (orderBy) => orderBy.map((entry) => ({ [entry.field]: entry.direction }));
61
+ const prismaConnectionArgs = ({ cursor, direction, node, skip, take }) => ({
62
+ ...cursor ? {
63
+ cursor: { id: cursor },
64
+ skip
65
+ } : null,
66
+ orderBy: toPrismaOrderBy(node.orderBy),
67
+ take: direction === "forward" ? take : -take
68
+ });
69
+ const getConflictingCountRequests = (node) => {
70
+ const signaturesByRelation = /* @__PURE__ */ new Map();
71
+ const requestsByRelation = /* @__PURE__ */ new Map();
72
+ for (const [field, computed] of node.computeds) {
73
+ if (!computed.select) continue;
74
+ for (const [selectionName, selection] of Object.entries(computed.select)) {
75
+ if (selection.kind !== "count") continue;
76
+ const signature = stableStringify(selection.where ?? null);
77
+ const signatures = signaturesByRelation.get(selection.relation) ?? /* @__PURE__ */ new Set();
78
+ signatures.add(signature);
79
+ signaturesByRelation.set(selection.relation, signatures);
80
+ const requests = requestsByRelation.get(selection.relation) ?? [];
81
+ requests.push({
82
+ field,
83
+ needName: selectionName,
84
+ relation: selection.relation,
85
+ where: selection.where
86
+ });
87
+ requestsByRelation.set(selection.relation, requests);
88
+ }
89
+ }
90
+ return new Map([...requestsByRelation.entries()].filter(([relation]) => (signaturesByRelation.get(relation)?.size ?? 0) > 1));
91
+ };
92
+ function createPrismaSourceAdapter({ prisma, views }) {
93
+ const viewConfigs = createPrismaViewConfigs({
94
+ prisma,
95
+ views
96
+ });
97
+ const sourceDefinitions = createSourceDefinitions(viewConfigs, { resolveRelation: inferPrismaRelation });
98
+ const sourcesByView = new Map(sourceDefinitions.map((source) => [source.view, source]));
99
+ const sourcesByFields = new Map(sourceDefinitions.map((source) => [source.view.fields, source]));
100
+ const delegates = new Map(viewConfigs.map((config, index) => [sourceDefinitions[index], (ctx) => config.delegate(ctx)]));
101
+ const getSource = (target) => {
102
+ if (isSourceDefinition(target)) return target;
103
+ const source = sourcesByView.get(target) ?? sourcesByFields.get(target.fields);
104
+ if (!source) throw new Error(`No source registered for view ${target.typeName}.`);
105
+ return source;
106
+ };
107
+ const getDelegate = (ctx, source) => {
108
+ const getSourceDelegate = delegates.get(source);
109
+ if (!getSourceDelegate) throw new Error(`No Prisma delegate registered for source ${source.view.typeName}.`);
110
+ return getSourceDelegate(ctx);
111
+ };
112
+ const countChildrenByParentKey = async ({ ctx, foreignKey, parentKeys, source, where }) => {
113
+ const delegate = getDelegate(ctx, source);
114
+ if (!delegate.groupBy) throw new Error(`Source ${source.view.typeName} does not support grouped count hydration.`);
115
+ const rows = await delegate.groupBy({
116
+ _count: { _all: true },
117
+ by: [foreignKey],
118
+ where: {
119
+ [foreignKey]: { in: parentKeys },
120
+ ...where ?? {}
121
+ }
122
+ });
123
+ return new Map(rows.map((row) => [row[foreignKey], row._count?._all ?? 0]));
124
+ };
125
+ const attachConflictingComputedCounts = async ({ ctx, items, node, source }) => {
126
+ if (items.length === 0) return items;
127
+ const conflictingRequests = getConflictingCountRequests(node);
128
+ for (const [relationName, requests] of conflictingRequests) {
129
+ const relation = source.relations?.[relationName];
130
+ if (!relation || relation.kind !== "many") throw new Error(`Conflicting computed counts on ${source.view.typeName}.${relationName} require a 'many' relation in the Prisma executor.`);
131
+ const childSource = resolveSourceReference(relation.source);
132
+ const parentKeys = [...new Set(items.map((item) => item[relation.localKey]).filter((value) => value !== null && value !== void 0))];
133
+ const assignmentsBySignature = /* @__PURE__ */ new Map();
134
+ for (const request of requests) {
135
+ const signature = stableStringify(request.where ?? null);
136
+ const assignment = assignmentsBySignature.get(signature) ?? {
137
+ requests: [],
138
+ where: request.where
139
+ };
140
+ assignment.requests.push(request);
141
+ assignmentsBySignature.set(signature, assignment);
142
+ }
143
+ for (const { requests: signatureRequests, where } of assignmentsBySignature.values()) {
144
+ const counts = await countChildrenByParentKey({
145
+ ctx,
146
+ foreignKey: relation.foreignKey,
147
+ parentKeys,
148
+ source: childSource,
149
+ where
150
+ });
151
+ for (const item of items) {
152
+ const parentKey = item[relation.localKey];
153
+ const count = counts.get(parentKey) ?? 0;
154
+ for (const request of signatureRequests) attachComputedState(item, request.field, { [request.needName]: count });
155
+ }
156
+ }
157
+ }
158
+ for (const [relationName, relationNode] of node.relations) {
159
+ const relation = source.relations?.[relationName];
160
+ if (!relation) continue;
161
+ const childSource = resolveSourceReference(relation.source);
162
+ await attachConflictingComputedCounts({
163
+ ctx,
164
+ items: items.flatMap((item) => {
165
+ const value = item[relationName];
166
+ if (Array.isArray(value)) return value.filter(isRecord);
167
+ return isRecord(value) ? [value] : [];
168
+ }),
169
+ node: relationNode,
170
+ source: childSource
171
+ });
172
+ }
173
+ return items;
174
+ };
175
+ const hydrateComputedCounts = async ({ ctx, items, plan }) => attachConflictingComputedCounts({
176
+ ctx,
177
+ items,
178
+ node: plan.root,
179
+ source: plan.source
180
+ });
181
+ const fetchByIds = async ({ ctx, extra, ids, plan }) => {
182
+ const delegate = getDelegate(ctx, plan.source);
183
+ if (!delegate.findMany) throw new Error(`Source ${plan.source.view.typeName} does not support byIds execution.`);
184
+ return hydrateComputedCounts({
185
+ ctx,
186
+ items: await delegate.findMany({
187
+ ...extra,
188
+ select: toPrismaSelect(plan),
189
+ where: { id: { in: ids } }
190
+ }),
191
+ plan
192
+ });
193
+ };
194
+ const fetchById = async ({ ctx, extra, id, plan }) => {
195
+ const delegate = getDelegate(ctx, plan.source);
196
+ if (delegate.findUnique) return (await hydrateComputedCounts({
197
+ ctx,
198
+ items: (await Promise.all([delegate.findUnique({
199
+ ...extra,
200
+ select: toPrismaSelect(plan),
201
+ where: { id }
202
+ })])).flatMap((item) => item ? [item] : []),
203
+ plan
204
+ }))[0] ?? null;
205
+ return (await fetchByIds({
206
+ ctx,
207
+ extra,
208
+ ids: [id],
209
+ plan
210
+ }))[0] ?? null;
211
+ };
212
+ const fetchConnection = async ({ ctx, cursor, direction, extra, plan, skip, take }) => {
213
+ const delegate = getDelegate(ctx, plan.source);
214
+ if (!delegate.findMany) throw new Error(`Source ${plan.source.view.typeName} does not support connection execution.`);
215
+ const hydrated = await hydrateComputedCounts({
216
+ ctx,
217
+ items: await delegate.findMany({
218
+ ...extra,
219
+ ...prismaConnectionArgs({
220
+ cursor,
221
+ direction,
222
+ node: plan.root,
223
+ skip,
224
+ take
225
+ }),
226
+ select: toPrismaSelect(plan)
227
+ }),
228
+ plan
229
+ });
230
+ return direction === "backward" ? [...hydrated].reverse() : hydrated;
231
+ };
232
+ const registry = createSourceRegistry(sourceDefinitions.map((source) => [source, {
233
+ byId: ({ ctx, extra, id, plan }) => fetchById({
234
+ ctx,
235
+ extra,
236
+ id,
237
+ plan
238
+ }),
239
+ byIds: ({ ctx, extra, ids, plan }) => fetchByIds({
240
+ ctx,
241
+ extra,
242
+ ids,
243
+ plan
244
+ }),
245
+ connection: ({ ctx, cursor, direction, extra, plan, skip, take }) => fetchConnection({
246
+ ctx,
247
+ cursor,
248
+ direction,
249
+ extra,
250
+ plan,
251
+ skip,
252
+ take
253
+ })
254
+ }]));
255
+ return {
256
+ fetchById,
257
+ fetchByIds,
258
+ fetchConnection,
259
+ getSource,
260
+ registry,
261
+ resolveById: ({ ctx, extra, id, input, view }) => resolveSourceById({
262
+ ctx,
263
+ extra,
264
+ id,
265
+ input,
266
+ registry,
267
+ source: getSource(view)
268
+ }),
269
+ resolveByIds: ({ ctx, extra, ids, input, view }) => resolveSourceByIds({
270
+ ctx,
271
+ extra,
272
+ ids,
273
+ input,
274
+ registry,
275
+ source: getSource(view)
276
+ }),
277
+ resolveConnection: ({ ctx, cursor, direction, extra, input, skip, take, view }) => resolveSourceConnection({
278
+ ctx,
279
+ cursor,
280
+ direction,
281
+ extra,
282
+ input,
283
+ registry,
284
+ skip,
285
+ source: getSource(view),
286
+ take
287
+ })
288
+ };
289
+ }
290
+ const createPrismaSourceRegistry = (options) => createPrismaSourceAdapter(options).registry;
291
+ function createPrismaFate({ procedure, ...options }) {
292
+ const adapter = createPrismaSourceAdapter(options);
293
+ const connection = withConnection(procedure);
294
+ const procedures = bindSourceProcedures({
295
+ createConnectionProcedure: connection,
296
+ procedure,
297
+ registry: adapter.registry
298
+ });
299
+ return {
300
+ ...adapter,
301
+ connection,
302
+ createPlan: ({ args, ctx, select, view }) => createSourcePlan({
303
+ args,
304
+ ctx,
305
+ select,
306
+ source: adapter.getSource(view)
307
+ }),
308
+ procedures: (input) => {
309
+ const procedureInput = input;
310
+ return procedures(procedureInput && typeof procedureInput === "object" && "view" in procedureInput ? {
311
+ ...procedureInput,
312
+ source: adapter.getSource(procedureInput.view)
313
+ } : adapter.getSource(input));
314
+ },
315
+ resolveById: ({ ctx, extra, id, input, view }) => resolveSourceById({
316
+ ctx,
317
+ extra,
318
+ id,
319
+ input,
320
+ registry: adapter.registry,
321
+ source: adapter.getSource(view)
322
+ }),
323
+ resolveByIds: ({ ctx, extra, ids, input, view }) => resolveSourceByIds({
324
+ ctx,
325
+ extra,
326
+ ids,
327
+ input,
328
+ registry: adapter.registry,
329
+ source: adapter.getSource(view)
330
+ }),
331
+ resolveConnection: ({ ctx, cursor, direction, extra, input, skip, take, view }) => resolveSourceConnection({
332
+ ctx,
333
+ cursor,
334
+ direction,
335
+ extra,
336
+ input,
337
+ registry: adapter.registry,
338
+ skip,
339
+ source: adapter.getSource(view),
340
+ take
341
+ })
342
+ };
343
+ }
344
+ //#endregion
345
+ export { createPrismaFate, createPrismaSourceAdapter, createPrismaSourceRegistry, prismaConnectionArgs };