@nkzw/fate 1.4.0 → 1.5.1

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 (191) hide show
  1. package/README.md +324 -0
  2. package/docs/api/classes/FateClient.md +51 -199
  3. package/docs/api/functions/clientRoot.md +1 -1
  4. package/docs/api/functions/createClient.md +1 -1
  5. package/docs/api/functions/createGraphQLTransport.md +1 -1
  6. package/docs/api/functions/createHTTPTransport.md +1 -1
  7. package/docs/api/functions/createTRPCTransport.md +5 -1
  8. package/docs/api/functions/defer.md +1 -1
  9. package/docs/api/functions/getDeferredMetadata.md +1 -1
  10. package/docs/api/functions/getListEntries.md +1 -1
  11. package/docs/api/functions/getSelectionPlan.md +1 -1
  12. package/docs/api/functions/graphqlMutation.md +1 -1
  13. package/docs/api/functions/isDeferred.md +1 -1
  14. package/docs/api/functions/isRecord.md +1 -1
  15. package/docs/api/functions/isViewTag.md +1 -1
  16. package/docs/api/functions/liveConnectionTopic.md +1 -1
  17. package/docs/api/functions/liveEntityTopic.md +1 -1
  18. package/docs/api/functions/liveGlobalConnectionTopic.md +1 -1
  19. package/docs/api/functions/mutation.md +1 -1
  20. package/docs/api/functions/toEntityId.md +1 -1
  21. package/docs/api/functions/view.md +1 -1
  22. package/docs/api/index.md +6 -1
  23. package/docs/api/interfaces/FateThenable.md +3 -3
  24. package/docs/api/interfaces/Persistence.md +5 -0
  25. package/docs/api/interfaces/PersistenceSession.md +109 -0
  26. package/docs/api/interfaces/Transport.md +46 -7
  27. package/docs/api/server/classes/FateRequestError.md +5 -5
  28. package/docs/api/server/drizzle/functions/createDrizzleFate.md +1 -1
  29. package/docs/api/server/drizzle/functions/createDrizzleSourceAdapter.md +1 -1
  30. package/docs/api/server/drizzle/functions/createDrizzleSourceRegistry.md +1 -1
  31. package/docs/api/server/drizzle/type-aliases/DrizzleManyToManyConfig.md +1 -1
  32. package/docs/api/server/drizzle/type-aliases/DrizzleManyToManyInput.md +1 -1
  33. package/docs/api/server/drizzle/type-aliases/DrizzleQueryExtra.md +3 -3
  34. package/docs/api/server/drizzle/type-aliases/DrizzleSourceAdapter.md +9 -9
  35. package/docs/api/server/drizzle/type-aliases/DrizzleViewConfig.md +1 -1
  36. package/docs/api/server/functions/bindSourceProcedures.md +1 -1
  37. package/docs/api/server/functions/computed.md +1 -1
  38. package/docs/api/server/functions/count.md +1 -1
  39. package/docs/api/server/functions/createFateFetchHandler.md +1 -1
  40. package/docs/api/server/functions/createFateServer.md +1 -1
  41. package/docs/api/server/functions/createHonoFateHandler.md +1 -1
  42. package/docs/api/server/functions/createLiveEventBus.md +1 -1
  43. package/docs/api/server/functions/createNestedSourcePlan.md +1 -1
  44. package/docs/api/server/functions/createResolver.md +1 -1
  45. package/docs/api/server/functions/createSourcePlan.md +1 -1
  46. package/docs/api/server/functions/createSourceProcedures.md +1 -1
  47. package/docs/api/server/functions/dataView.md +1 -1
  48. package/docs/api/server/functions/field.md +1 -1
  49. package/docs/api/server/functions/getNestedSelection.md +1 -1
  50. package/docs/api/server/functions/getScopedArgs.md +1 -1
  51. package/docs/api/server/functions/hasNestedSelection.md +1 -1
  52. package/docs/api/server/functions/list.md +1 -1
  53. package/docs/api/server/functions/refetchSourceById.md +1 -1
  54. package/docs/api/server/functions/resolveSourceById.md +1 -1
  55. package/docs/api/server/functions/resolveSourceByIds.md +1 -1
  56. package/docs/api/server/functions/resolveSourceConnection.md +1 -1
  57. package/docs/api/server/functions/resolver.md +1 -1
  58. package/docs/api/server/functions/toPrismaSelect.md +1 -1
  59. package/docs/api/server/functions/withConnection.md +1 -1
  60. package/docs/api/server/prisma/functions/createPrismaFate.md +1 -1
  61. package/docs/api/server/prisma/functions/createPrismaSourceAdapter.md +1 -1
  62. package/docs/api/server/prisma/functions/createPrismaSourceRegistry.md +1 -1
  63. package/docs/api/server/prisma/functions/prismaConnectionArgs.md +1 -1
  64. package/docs/api/server/prisma/type-aliases/PrismaDelegate.md +4 -4
  65. package/docs/api/server/prisma/type-aliases/PrismaQueryExtra.md +1 -1
  66. package/docs/api/server/prisma/type-aliases/PrismaSourceAdapter.md +9 -9
  67. package/docs/api/server/prisma/type-aliases/PrismaViewConfig.md +1 -1
  68. package/docs/api/server/type-aliases/ComputedField.md +5 -5
  69. package/docs/api/server/type-aliases/ComputedSelection.md +1 -1
  70. package/docs/api/server/type-aliases/ConnectionItem.md +3 -3
  71. package/docs/api/server/type-aliases/ConnectionPagination.md +5 -5
  72. package/docs/api/server/type-aliases/ConnectionResult.md +3 -3
  73. package/docs/api/server/type-aliases/CountSelection.md +4 -4
  74. package/docs/api/server/type-aliases/CountWhere.md +1 -1
  75. package/docs/api/server/type-aliases/DataViewListOptions.md +2 -2
  76. package/docs/api/server/type-aliases/DataViewOrderBy.md +1 -1
  77. package/docs/api/server/type-aliases/DataViewOrderDirection.md +1 -1
  78. package/docs/api/server/type-aliases/DataViewResult.md +1 -1
  79. package/docs/api/server/type-aliases/Entity.md +1 -1
  80. package/docs/api/server/type-aliases/FateServer.md +5 -5
  81. package/docs/api/server/type-aliases/FateServerManifest.md +1 -1
  82. package/docs/api/server/type-aliases/FieldSelection.md +3 -3
  83. package/docs/api/server/type-aliases/LiveConnectionEventType.md +1 -1
  84. package/docs/api/server/type-aliases/LiveConnectionSourceEvent.md +1 -1
  85. package/docs/api/server/type-aliases/LiveEventBus.md +1 -1
  86. package/docs/api/server/type-aliases/LiveEventType.md +1 -1
  87. package/docs/api/server/type-aliases/LiveSourceEvent.md +1 -1
  88. package/docs/api/server/type-aliases/NativeFateAPI.md +4 -4
  89. package/docs/api/server/type-aliases/OrderDirection.md +1 -1
  90. package/docs/api/server/type-aliases/SourceConfig.md +6 -6
  91. package/docs/api/server/type-aliases/SourceDefinition.md +6 -6
  92. package/docs/api/server/type-aliases/SourceOrder.md +1 -1
  93. package/docs/api/server/type-aliases/SourceOrderField.md +3 -3
  94. package/docs/api/server/type-aliases/SourcePlan.md +1 -1
  95. package/docs/api/server/type-aliases/SourcePlanNode.md +1 -1
  96. package/docs/api/server/type-aliases/SourceRegistry.md +1 -1
  97. package/docs/api/server/type-aliases/SourceRelation.md +1 -1
  98. package/docs/api/server/type-aliases/SourceRelationConfig.md +1 -1
  99. package/docs/api/server/variables/byIdInput.md +1 -1
  100. package/docs/api/server/variables/connectionArgs.md +1 -1
  101. package/docs/api/type-aliases/ConnectionMetadata.md +1 -1
  102. package/docs/api/type-aliases/ConnectionRef.md +1 -1
  103. package/docs/api/type-aliases/Deferred.md +1 -1
  104. package/docs/api/type-aliases/DeferredMetadata.md +1 -1
  105. package/docs/api/type-aliases/DeferredSelection.md +1 -1
  106. package/docs/api/type-aliases/DeferredSnapshot.md +1 -1
  107. package/docs/api/type-aliases/Entity.md +2 -2
  108. package/docs/api/type-aliases/EntityId.md +1 -1
  109. package/docs/api/type-aliases/FateDehydratedState.md +1 -1
  110. package/docs/api/type-aliases/FateLiveConnectionEvent.md +1 -1
  111. package/docs/api/type-aliases/FateLiveEvent.md +1 -1
  112. package/docs/api/type-aliases/FateMutations.md +1 -1
  113. package/docs/api/type-aliases/FateOperation.md +2 -2
  114. package/docs/api/type-aliases/FateProtocolRequest.md +1 -1
  115. package/docs/api/type-aliases/FateProtocolResponse.md +1 -1
  116. package/docs/api/type-aliases/FateRecord.md +1 -1
  117. package/docs/api/type-aliases/FateRoots.md +1 -1
  118. package/docs/api/type-aliases/GraphQLMutationDefinition.md +1 -1
  119. package/docs/api/type-aliases/GraphQLMutationInput.md +1 -1
  120. package/docs/api/type-aliases/GraphQLMutationMap.md +1 -1
  121. package/docs/api/type-aliases/GraphQLMutationOutput.md +1 -1
  122. package/docs/api/type-aliases/GraphQLTransportOptions.md +19 -11
  123. package/docs/api/type-aliases/HydrateOptions.md +1 -1
  124. package/docs/api/type-aliases/HydrationLimits.md +1 -1
  125. package/docs/api/type-aliases/InferFateAPI.md +1 -1
  126. package/docs/api/type-aliases/List.md +1 -1
  127. package/docs/api/type-aliases/ListEntry.md +1 -1
  128. package/docs/api/type-aliases/ListItem.md +1 -1
  129. package/docs/api/type-aliases/Mask.md +1 -1
  130. package/docs/api/type-aliases/MutationDefinition.md +1 -1
  131. package/docs/api/type-aliases/MutationEntity.md +1 -1
  132. package/docs/api/type-aliases/MutationIdentifier.md +1 -1
  133. package/docs/api/type-aliases/MutationIdentity.md +7 -0
  134. package/docs/api/type-aliases/MutationInput.md +1 -1
  135. package/docs/api/type-aliases/MutationResult.md +1 -1
  136. package/docs/api/type-aliases/NodesItem.md +1 -1
  137. package/docs/api/type-aliases/Pagination.md +5 -5
  138. package/docs/api/type-aliases/PersistedMutationStatus.md +5 -0
  139. package/docs/api/type-aliases/PersistenceSnapshot.md +5 -0
  140. package/docs/api/type-aliases/Request.md +1 -1
  141. package/docs/api/type-aliases/RequestMode.md +1 -1
  142. package/docs/api/type-aliases/RequestOptions.md +2 -2
  143. package/docs/api/type-aliases/RequestPersistenceOptions.md +5 -0
  144. package/docs/api/type-aliases/RequestResult.md +1 -1
  145. package/docs/api/type-aliases/Selection.md +1 -1
  146. package/docs/api/type-aliases/TypeConfig.md +4 -4
  147. package/docs/api/type-aliases/View.md +1 -1
  148. package/docs/api/type-aliases/ViewData.md +1 -1
  149. package/docs/api/type-aliases/ViewEntity.md +1 -1
  150. package/docs/api/type-aliases/ViewEntityName.md +1 -1
  151. package/docs/api/type-aliases/ViewRef.md +1 -1
  152. package/docs/api/type-aliases/ViewSelection.md +1 -1
  153. package/docs/api/type-aliases/ViewSnapshot.md +1 -1
  154. package/docs/api/type-aliases/ViewTag.md +1 -1
  155. package/docs/api/variables/ConnectionTag.md +1 -1
  156. package/docs/api/variables/DeferTag.md +1 -1
  157. package/docs/api/variables/DeferredTag.md +1 -1
  158. package/docs/guide/getting-started.md +2 -0
  159. package/docs/guide/persistence.md +321 -0
  160. package/lib/{liveTopics-uVP0LG-Q.mjs → args-CRLIRl_v.mjs} +1 -59
  161. package/lib/{executor-BRudKWDY.d.mts → executor-oPTYqgQV.d.mts} +1 -1
  162. package/lib/{graphqlTransport-BDR1pnUQ.d.mts → graphqlTransport-CGYE4NdD.d.mts} +3 -2
  163. package/lib/{graphqlTransport-DSBVS2Fq.mjs → graphqlTransport-DmheG3AO.mjs} +3 -2
  164. package/lib/graphqlTransport.d.mts +1 -1
  165. package/lib/graphqlTransport.mjs +1 -1
  166. package/lib/hydration-DPZRJgnu.mjs +273 -0
  167. package/lib/idempotency-types-DuqJ7KSd.d.mts +16 -0
  168. package/lib/idempotency.d.mts +26 -0
  169. package/lib/idempotency.mjs +34 -0
  170. package/lib/index.d.mts +5 -5
  171. package/lib/index.mjs +275 -1567
  172. package/lib/{list-Bb1SeABn.d.mts → list-5hrTVoiB.d.mts} +1 -1
  173. package/lib/list.d.mts +1 -1
  174. package/lib/liveTopics-DuFkDZQm.mjs +17 -0
  175. package/lib/persistence.d.mts +40 -0
  176. package/lib/persistence.mjs +1730 -0
  177. package/lib/protocol-DS5sf6sd.mjs +44 -0
  178. package/lib/{record-BTUXkHQU.d.mts → record-Dxjvpsep.d.mts} +8 -4
  179. package/lib/server/drizzle.d.mts +2 -2
  180. package/lib/server/drizzle.mjs +1 -1
  181. package/lib/server/prisma.d.mts +2 -2
  182. package/lib/server/prisma.mjs +1 -6
  183. package/lib/server.d.mts +3 -3
  184. package/lib/server.mjs +19 -7
  185. package/lib/sortObjectKeys-yhuitEQZ.mjs +9 -0
  186. package/lib/{sourceRouter-DSaADXSf.mjs → sourceRouter-51POBlEE.mjs} +9 -6
  187. package/lib/store-CakBBzWG.mjs +1386 -0
  188. package/lib/{transport-Bo1Jgo9R.d.mts → transport-DR0fwleU.d.mts} +607 -412
  189. package/lib/vite.mjs +18 -10
  190. package/package.json +12 -2
  191. package/docs/api/type-aliases/Snapshot.md +0 -7
@@ -555,368 +555,6 @@ interface Router<TRoot extends AnyRootTypes, TRecord extends RouterRecord> {
555
555
  }
556
556
  type AnyRouter = Router<any, any>;
557
557
  //#endregion
558
- //#region src/cache.d.ts
559
- declare class ViewDataCache {
560
- private readonly isEnabled;
561
- constructor(isEnabled?: () => boolean);
562
- private cache;
563
- private rootDependencies;
564
- private dependencyIndex;
565
- clear(): void;
566
- get<T extends Entity, S extends Selection<T>, V extends View<T, S>>(entityId: EntityId, view: V, ref: ViewRef<T['__typename']>): FateThenable<ViewSnapshot<T, S>> | null;
567
- set<T extends Entity, S extends Selection<T>, V extends View<T, S>>(entityId: EntityId, view: V, ref: ViewRef<T['__typename']>, thenable: FateThenable<ViewSnapshot<T, S>>, dependencies: ReadonlySet<EntityId>): void;
568
- invalidate(entityId: EntityId): void;
569
- private invalidateDependents;
570
- private delete;
571
- }
572
- //#endregion
573
- //#region src/store.d.ts
574
- type List = Readonly<{
575
- backwardPageLimit?: number;
576
- cursors?: ReadonlyArray<string | undefined>;
577
- forwardPageLimit?: number;
578
- ids: ReadonlyArray<EntityId>;
579
- liveAfterIds?: ReadonlyArray<EntityId>;
580
- liveBeforeIds?: ReadonlyArray<EntityId>;
581
- pagination?: Pagination;
582
- pendingAfterIds?: ReadonlyArray<EntityId>;
583
- pendingBeforeIds?: ReadonlyArray<EntityId>;
584
- }>;
585
- type StoreHydrationState = Readonly<{
586
- coverage: ReadonlyArray<readonly [EntityId, ReadonlyArray<string>]>;
587
- lists: ReadonlyArray<readonly [string, List]>;
588
- records: ReadonlyArray<readonly [EntityId, AnyRecord]>;
589
- }>;
590
- declare class Store {
591
- private readonly onRebase?;
592
- private coverage;
593
- private listKeysByOwnerField;
594
- private listKeysByReferencedEntity;
595
- private lists;
596
- private recordReferenceFields;
597
- private recordReferencesByTarget;
598
- private records;
599
- private subscriptions;
600
- private listSubscriptions;
601
- private readonly optimisticLayers;
602
- private readonly optimisticBase;
603
- private recordingLayer;
604
- private rebase;
605
- constructor(onRebase?: ((ids: ReadonlySet<EntityId>) => void) | undefined);
606
- get hasOptimisticUpdates(): boolean;
607
- get isRebasing(): boolean;
608
- /** Apply a synchronous cache update beneath the pending optimistic layers. */
609
- update<T>(apply: () => T): T;
610
- private getRebaseChanges;
611
- /** Returns an idempotent settlement function; omit its update to roll back. */
612
- optimisticUpdate(apply: () => void): (commit?: () => void) => void;
613
- private getPendingOverlap;
614
- private captureRecord;
615
- private captureList;
616
- dehydrate(): StoreHydrationState;
617
- hydrate(state: StoreHydrationState, mode: 'preserve-existing' | 'replace', options?: {
618
- deferNotifications?: boolean;
619
- }): () => void;
620
- private rebuildIndexes;
621
- read(id: EntityId): AnyRecord | undefined;
622
- merge(id: EntityId, partial: AnyRecord, paths: Iterable<string>): void;
623
- private mergeInternal;
624
- deleteRecord(id: EntityId): void;
625
- missingForSelection(id: EntityId, paths: Iterable<string>): Set<string>;
626
- subscribe(id: EntityId, selection: ReadonlySet<string> | null, fn: () => void): () => void;
627
- subscribe(id: EntityId, fn: () => void): () => void;
628
- private notify;
629
- private notifyListSubscribers;
630
- getList(key: string): ReadonlyArray<EntityId> | undefined;
631
- getListState(key: string): List | undefined;
632
- getListsForField(ownerId: EntityId, field: string): Array<readonly [string, List]>;
633
- setList(key: string, state: List): void;
634
- replaceListEntityId(previousId: EntityId, nextId: EntityId): void;
635
- restoreList(key: string, list?: List): void;
636
- collectGarbage(markedRecords: ReadonlySet<EntityId>, markedLists: ReadonlySet<string>, options?: {
637
- onRecordDeleted?: (id: EntityId) => void;
638
- }): {
639
- lists: Set<string>;
640
- records: Set<EntityId>;
641
- };
642
- private deleteList;
643
- subscribeList(key: string, fn: () => void): () => void;
644
- removeReferencesTo(targetId: EntityId, viewDataCache: ViewDataCache): void;
645
- private restore;
646
- private addListIndexes;
647
- private removeListIndexes;
648
- private getListReferencedEntityIds;
649
- private getRecordFieldReferences;
650
- private addRecordFieldReferenceIndex;
651
- private removeRecordFieldReferenceIndex;
652
- private addRecordReferenceIndexes;
653
- private removeRecordReferenceIndexes;
654
- private updateRecordReferenceIndexes;
655
- }
656
- //#endregion
657
- //#region src/hydration.d.ts
658
- /** JSON-safe opaque value contained in a dehydrated fate snapshot. */
659
- type FateSerializedValue = null | boolean | number | string | ReadonlyArray<FateSerializedValue> | Readonly<{
660
- [key: string]: FateSerializedValue;
661
- }>;
662
- /** Versioned, JSON-safe durable cache snapshot produced by `FateClient.dehydrate()`. */
663
- declare const hydrationScopeBrand: unique symbol;
664
- type FateDehydratedState<Scope extends string = string> = Readonly<{
665
- data: FateSerializedValue;
666
- readonly [hydrationScopeBrand]?: Scope;
667
- scope: Scope;
668
- version: 1;
669
- }>;
670
- /** Controls how `FateClient.hydrate()` reconciles a snapshot with browser cache state. */
671
- type HydrateOptions = Readonly<{
672
- /**
673
- * `preserve-existing` keeps browser values and list windows when conflicts
674
- * occur. `replace` treats the snapshot as authoritative.
675
- *
676
- * @defaultValue 'preserve-existing'
677
- */
678
- merge?: 'preserve-existing' | 'replace';
679
- }>;
680
- /** Resource limits applied while encoding and decoding hydration snapshots. */
681
- type HydrationLimits = Readonly<{
682
- /** Maximum number of entries in any encoded array or object. */
683
- maxCollectionLength: number;
684
- /** Maximum number of encoded values in a hydration snapshot. */
685
- maxNodes: number;
686
- /** Maximum length of an encoded string, object key, or bigint payload. */
687
- maxStringLength: number;
688
- }>;
689
- //#endregion
690
- //#region src/selection.d.ts
691
- /**
692
- * Representation of a composed selection including hashed args and the
693
- * flat set of field paths to read or fetch.
694
- */
695
- type SelectionPlan = {
696
- readonly args: Map<string, Readonly<{
697
- hash: string;
698
- ignoreKeys?: ReadonlySet<string>;
699
- value: AnyRecord;
700
- }>>;
701
- readonly live: Map<string, ConnectionLivePolicy>;
702
- readonly paths: Set<string>;
703
- };
704
- /**
705
- * Flattens a view into a `SelectionPlan`, expanding composed views and
706
- * partitioning nested args so the client can fetch exactly what is declared.
707
- */
708
- declare const getSelectionPlan: <T extends Entity, S extends Selection<T>, V extends View<T, S>>(viewComposition: V, ref: ViewRef<T['__typename']> | null) => SelectionPlan;
709
- //#endregion
710
- //#region src/operation-lifetime.d.ts
711
- type RetainHandle = Readonly<{
712
- dispose(): void;
713
- }>;
714
- //#endregion
715
- //#region src/client.d.ts
716
- /**
717
- * Strategy used when resolving a request.
718
- */
719
- type RequestMode =
720
- /** (default) Use cached data if present, otherwise fetch. */
721
- 'cache-first' |
722
- /** Show cached data immediately and refresh in the background. */
723
- 'stale-while-revalidate' |
724
- /** Always fetch from the network and ignore cached entries. */
725
- 'network-only';
726
- /**
727
- * Request options that affect how requests are fetched and retained.
728
- */
729
- type RequestOptions = Readonly<{
730
- mode?: RequestMode;
731
- }>;
732
- type DeferredSnapshot<T> = Readonly<{
733
- coverage: ReadonlyArray<readonly [id: EntityId, paths: ReadonlySet<string>]>;
734
- data: T;
735
- }>;
736
- type FateClientOptions<Roots extends FateRoots, Mutations extends FateMutations, HydrationScope extends string> = {
737
- /**
738
- * Number of recently released requests to keep retained before their records
739
- * and lists are eligible for garbage collection.
740
- *
741
- * @defaultValue 10
742
- */
743
- gcReleaseBufferSize?: number;
744
- /**
745
- * Bounds hydration snapshot encoding and decoding work.
746
- */
747
- hydrationLimits?: Partial<HydrationLimits>;
748
- /**
749
- * Identifies snapshots compatible with this client. Change this value when
750
- * deploying an incompatible cache schema or separating cache namespaces.
751
- */
752
- hydrationScope?: HydrationScope;
753
- mutations?: Mutations;
754
- onLiveError?: (error: unknown) => void;
755
- roots: Roots;
756
- transport: Transport<MutationMapFromDefinitions<Mutations>>;
757
- types: ReadonlyArray<Omit<TypeConfig, 'getId'> & Partial<{
758
- getId: TypeConfig['getId'];
759
- }>>;
760
- };
761
- /**
762
- * Core client that normalizes records, manages the view cache, and coordinates
763
- * data fetching.
764
- */
765
- declare class FateClient<Roots extends FateRoots, Mutations extends FateMutations, HydrationScope extends string = string> {
766
- private readonly mutationMap;
767
- private readonly parentLists;
768
- private readonly rootLists;
769
- private readonly pending;
770
- private readonly pendingDeferred;
771
- private readonly pendingOptimisticMutations;
772
- private readonly optimisticEntityResolutions;
773
- private readonly onLiveError;
774
- private readonly liveSubscriptions;
775
- private readonly liveConnectionInvalidations;
776
- private readonly stableRefs;
777
- private readonly requests;
778
- private readonly rootRequests;
779
- private readonly stalledRequests;
780
- private gcPending;
781
- private gcScheduled;
782
- private pendingNetworkRequests;
783
- readonly store: Store;
784
- private readonly operationLifetime;
785
- private readonly hydrationLimits;
786
- private readonly hydrationScope;
787
- private readonly types;
788
- private readonly transport;
789
- private readonly viewDataCache;
790
- private liveConnectionInvalidationToken;
791
- readonly actions: MutationActionsFor<Mutations>;
792
- readonly mutations: MutationFunctionsFor<Mutations>;
793
- readonly roots: Roots;
794
- constructor(options: FateClientOptions<Roots, Mutations, HydrationScope>);
795
- private initializeParentLists;
796
- /**
797
- * Exports the durable normalized cache as an opaque JSON-safe value for SSR
798
- * transfer or persistence. Runtime requests, subscriptions, retainers, and
799
- * optimistic state are intentionally excluded.
800
- */
801
- dehydrate(): FateDehydratedState<HydrationScope>;
802
- /**
803
- * Restores a durable normalized cache snapshot without restoring runtime
804
- * request handles, retainers, subscriptions, or optimistic update state.
805
- * Hydrate before rendering SSR content. Replaying the same snapshot is safe.
806
- */
807
- hydrate(state: FateDehydratedState<HydrationScope>, options?: HydrateOptions): void;
808
- private registerRootList;
809
- private applyListInsert;
810
- private insertIntoRootLists;
811
- getTypeConfig(type: string): TypeConfig;
812
- private getListNodeType;
813
- executeMutation(key: string, input: unknown, select: Set<string>, options?: {
814
- args?: AnyRecord;
815
- plan?: SelectionPlan;
816
- }): Promise<unknown>;
817
- write(type: string, data: AnyRecord, select: ReadonlySet<string>, plan?: SelectionPlan, insert?: InsertPosition): string;
818
- deleteRecord(type: string, id: string | number): void;
819
- private stableRefWithViewNames;
820
- ref<T extends Entity>(type: T['__typename'], id: string | number, view: View<T, Selection<T>>): ViewRef<T['__typename']>;
821
- rootListRef(entityId: EntityId, rootView: View<any, any>): Readonly<{
822
- __typename: string;
823
- id: string | number;
824
- [ViewsTag]: Set<string>;
825
- }>;
826
- readView<T extends Entity, S extends Selection<T>, V extends View<T, S>>(view: V, ref: ViewRef<T['__typename']>): FateThenable<ViewSnapshot<T, S>>;
827
- readDeferred<T>(deferred: Deferred<T>): PromiseLike<DeferredSnapshot<T>>;
828
- assertLiveViewSupport(): void;
829
- assertLiveConnectionSupport(): void;
830
- subscribeLiveView<T extends Entity, S extends Selection<T>, V extends View<T, S>>(view: V, ref: ViewRef<T['__typename']>): () => void;
831
- subscribeLiveListView<V extends View<any, any>>(view: V, connection: ConnectionMetadata): () => void;
832
- private applyLiveConnectionEvent;
833
- private invalidateLiveConnection;
834
- private deleteConnectionEdge;
835
- private insertConnectionEdge;
836
- private syncNestedConnectionOwnerField;
837
- private getConnectionInsertIndex;
838
- private removeEntityFromListState;
839
- private mergeListState;
840
- registerPendingOptimisticMutation(entityId: EntityId, promise: Promise<unknown>): void;
841
- resolveOptimisticEntity(optimisticEntityId: EntityId, resolvedEntityId: EntityId): void;
842
- private getPendingOptimisticMutations;
843
- loadConnection<V extends View<any, any>>(view: V, connection: ConnectionMetadata, args: Record<string, unknown>, options?: {
844
- direction?: 'forward' | 'backward';
845
- }): Promise<Readonly<{
846
- backwardPageLimit?: number;
847
- cursors?: ReadonlyArray<string | undefined>;
848
- forwardPageLimit?: number;
849
- ids: ReadonlyArray<EntityId>;
850
- liveAfterIds?: ReadonlyArray<EntityId>;
851
- liveBeforeIds?: ReadonlyArray<EntityId>;
852
- pagination?: Pagination;
853
- pendingAfterIds?: ReadonlyArray<EntityId>;
854
- pendingBeforeIds?: ReadonlyArray<EntityId>;
855
- }> | undefined>;
856
- private loadConnectionInternal;
857
- request<R extends Request$1>(request: R, options?: RequestOptions): Promise<RequestResult<Roots, R>>;
858
- requestForRender<R extends Request$1>(request: R, options?: RequestOptions): Promise<RequestResult<Roots, R>>;
859
- prepareRequestForRender<R extends Request$1>(request: R, options: RequestOptions | undefined): Readonly<{
860
- promise: Promise<RequestResult<Roots, R>>;
861
- requestKey: string;
862
- }>;
863
- private requestWithDescriptor;
864
- releaseRequest(request: Request$1, mode: RequestMode): void;
865
- releaseRequestKey(requestKey: string, mode: RequestMode): void;
866
- retainRequestKey(requestKey: string, mode?: RequestMode): RetainHandle;
867
- /**
868
- * Keeps the records and lists reachable from a request alive until the
869
- * returned handle is disposed.
870
- *
871
- * `useRequest` calls this automatically while the component is mounted.
872
- * Use it directly for non-React request lifetimes, tests, or preloaded data
873
- * that must survive manual garbage collection.
874
- */
875
- retain(request: Request$1): RetainHandle;
876
- private scheduleGarbageCollection;
877
- /**
878
- * Removes records and lists that are not reachable from retained requests or
879
- * the release buffer.
880
- *
881
- * Garbage collection is scheduled automatically when retained requests are
882
- * released. Calling this method manually is mainly useful in tests and custom
883
- * memory-management flows.
884
- */
885
- gc(): void;
886
- private executeRequestHandle;
887
- private markRecordReferences;
888
- private hasActiveOptimisticUpdates;
889
- private hasPendingRequests;
890
- trackPendingRequest<T>(request: () => Promise<T>): Promise<T>;
891
- private runPendingGarbageCollection;
892
- private handleStoreAndNetworkRequest;
893
- private getRootType;
894
- private createRequestDescriptor;
895
- getRequestKey(request: Request$1): string;
896
- private hasRootListData;
897
- private executeRequest;
898
- private hasRequestData;
899
- getRequestResult<R extends Request$1>(request: R): RequestResult<Roots, R>;
900
- private getRequestResultFromDescriptor;
901
- private fetchByIdAndNormalize;
902
- private fetchQueryAndNormalize;
903
- private fetchListAndNormalize;
904
- private writeEntity;
905
- private linkParentLists;
906
- private readViewSelection;
907
- private clearStalledRequestsForEntity;
908
- private pendingPrefix;
909
- private pendingKey;
910
- private deferredPendingKey;
911
- private deferredSelectionSignature;
912
- private hasMissingDeferredList;
913
- private liveSubscriptionKey;
914
- private liveConnectionSubscriptionKey;
915
- private releaseLiveSubscription;
916
- private reportLiveError;
917
- }
918
- declare function createClient<T extends [FateRoots, FateMutations] = [Record<never, RootDefinition<any, any>>, Record<never, MutationDefinition<any, any, any>>], HydrationScope extends string = string>(options: FateClientOptions<T[0], T[1], HydrationScope>): FateClient<T[0], T[1], HydrationScope>;
919
- //#endregion
920
558
  //#region src/mutation.d.ts
921
559
  /**
922
560
  * Defines a mutation for a given entity type, preserving the input and output
@@ -939,6 +577,8 @@ type MutationOptions<Identifier extends MutationIdentifier<any, any, any>> = {
939
577
  insert?: InsertPosition;
940
578
  /** Optional optimistic update to apply immediately. */
941
579
  optimistic?: OptimisticUpdate<MutationResult<Identifier>>;
580
+ /** Skip durable delivery for this call, even when persistence is configured. */
581
+ persist?: boolean;
942
582
  /** Optional view specifying which fields to select from the server. */
943
583
  view?: View<MutationEntity<Identifier>, Selection<MutationEntity<Identifier>>>;
944
584
  };
@@ -980,6 +620,17 @@ type FateMutations = Record<string, MutationDefinition<any, any, any>>;
980
620
  type MutationTreeFromRecord<Mutations extends FateMutations, ValueMap extends Record<string, unknown>> = [keyof Mutations] extends [never] ? object : UnionToIntersection<{ [K in keyof Mutations & string]: NestedValue<K, ValueMap[K]>; }[keyof Mutations & string]>;
981
621
  type MutationFunctionsFor<Mutations extends FateMutations> = MutationTreeFromRecord<Mutations, { [K in keyof Mutations & string]: MutationFunction<MutationIdentifierFor<K, Mutations[K]>>; }>;
982
622
  type MutationActionsFor<Mutations extends FateMutations> = MutationTreeFromRecord<Mutations, { [K in keyof Mutations & string]: MutationAction<MutationIdentifierFor<K, Mutations[K]>>; }>;
623
+ /** @internal Serializable input to a live or restored mutation. */
624
+ type MutationCommand = {
625
+ args?: AnyRecord;
626
+ delete?: boolean;
627
+ entity: string;
628
+ input: AnyRecord;
629
+ insert: InsertPosition;
630
+ key: string;
631
+ optimistic?: AnyRecord;
632
+ plan?: SelectionPlan;
633
+ };
983
634
  //#endregion
984
635
  //#region src/types.d.ts
985
636
  /** Canonical runtime name for an entity type as returned by the server. */
@@ -1261,59 +912,597 @@ type ListResult<Item extends AnyRequestItem, Type extends TypeName, Result> = It
1261
912
  pagination?: Pagination;
1262
913
  }> : Array<ViewRef<Type>> : never;
1263
914
  /**
1264
- * The result of a `FateClient.request` and `useRequest` call, mapping each
1265
- * request key to its corresponding result.
915
+ * The result of a `FateClient.request` and `useRequest` call, mapping each
916
+ * request key to its corresponding result.
917
+ */
918
+ type RequestResult<R extends FateRoots, Q extends AnyRequest> = { [K in keyof Q]: K extends keyof R ? ListResult<Q[K], RootType<R[K]>, RootResult<R[K]>> : never; };
919
+ /** Brand used on root definitions to mark their identity in the d.ts output. */
920
+ declare const RootKind = "__fate__root";
921
+ /** Brand used on mutation definitions to mark their identity in the d.ts output. */
922
+ declare const MutationKind = "__fate__mutation";
923
+ /** Metadata describing a root query for a particular entity and result shape. */
924
+ type RootDefinition<Type extends TypeName, Result> = Readonly<{
925
+ [RootKind]: true;
926
+ type: Type;
927
+ }> & __RootResultAnchor<Result> & __RootTypeAnchor<Type>;
928
+ /** Minimal root description used for typing root maps. */
929
+ type FateRoots = Record<string, RootDefinition<TypeName, unknown>>;
930
+ /** Extracts the entity type name from a root definition. */
931
+ type RootType<R> = R extends __RootTypeAnchor<infer T> ? T : never;
932
+ /** Extracts the result type from a root definition. */
933
+ type RootResult<R> = R extends __RootResultAnchor<infer Data> ? Data : never;
934
+ /** Metadata describing a mutation for a particular entity, input, and output. */
935
+ type MutationDefinition<T extends Entity, I, R> = Readonly<{
936
+ entity: T['__typename'];
937
+ [MutationKind]: true;
938
+ }> & __MutationEntityAnchor<T> & __MutationInputAnchor<I> & __MutationResultAnchor<R>;
939
+ type MutationIdentifier<T extends Entity, I, R> = MutationDefinition<T, I, R> & Readonly<{
940
+ key: string;
941
+ }>;
942
+ /** Extracts the input type from a mutation definition or identifier. */
943
+ type MutationInput<M> = M extends __MutationInputAnchor<infer I> ? I : never;
944
+ /** Extracts the result type from a mutation definition or identifier. */
945
+ type MutationResult<M> = M extends __MutationResultAnchor<infer R> ? R : never;
946
+ /** Extracts the entity type from a mutation definition or identifier. */
947
+ type MutationEntity<M> = M extends __MutationEntityAnchor<infer E> ? E : never;
948
+ /** Minimal mutation description used for transport typing. */
949
+ type MutationShape = {
950
+ input: unknown;
951
+ output: unknown;
952
+ };
953
+ /**
954
+ * Convenience helper that maps mutation definitions to their input/output
955
+ * shapes for use by transports.
956
+ */
957
+ type MutationMapFromDefinitions<D extends FateMutations> = { [K in keyof D]: {
958
+ input: MutationInput<D[K]>;
959
+ output: MutationResult<D[K]>;
960
+ }; };
961
+ type OptimisticUpdateValue<T> = T extends ReadonlyArray<infer U> ? Array<OptimisticUpdateValue<U>> : NonNullish<T> extends AnyRecord ? OptimisticUpdate<NonNullish<T>> | Nullish<T> : NonNullish<T> | Nullish<T>;
962
+ /** Shape used to describe optimistic updates for mutations. */
963
+ type OptimisticUpdate<T> = { [K in keyof T]?: OptimisticUpdateValue<T[K]>; };
964
+ /** Promise-like value returned by cache reads that already have a resolved payload for React `use`. */
965
+ interface FateThenable<T> extends PromiseLike<T> {
966
+ status: 'fulfilled';
967
+ value: T;
968
+ }
969
+ //#endregion
970
+ //#region src/selection.d.ts
971
+ /**
972
+ * Representation of a composed selection including hashed args and the
973
+ * flat set of field paths to read or fetch.
974
+ */
975
+ type SelectionPlan = {
976
+ readonly args: Map<string, Readonly<{
977
+ hash: string;
978
+ ignoreKeys?: ReadonlySet<string>;
979
+ value: AnyRecord;
980
+ }>>;
981
+ readonly live: Map<string, ConnectionLivePolicy>;
982
+ readonly paths: Set<string>;
983
+ };
984
+ /**
985
+ * Flattens a view into a `SelectionPlan`, expanding composed views and
986
+ * partitioning nested args so the client can fetch exactly what is declared.
987
+ */
988
+ declare const getSelectionPlan: <T extends Entity, S extends Selection<T>, V extends View<T, S>>(viewComposition: V, ref: ViewRef<T['__typename']> | null) => SelectionPlan;
989
+ //#endregion
990
+ //#region src/request-descriptor.d.ts
991
+ type NodeRequestDescriptor = Readonly<{
992
+ ids: ReadonlyArray<string | number>;
993
+ kind: 'node' | 'nodes';
994
+ name: string;
995
+ plan: SelectionPlan;
996
+ refViewNames: ReadonlySet<string>;
997
+ type: string;
998
+ viewSignature: string;
999
+ }>;
1000
+ type QueryRequestDescriptor = Readonly<{
1001
+ argsPayload: ResolvedArgsPayload | undefined;
1002
+ kind: 'query';
1003
+ name: string;
1004
+ plan: SelectionPlan;
1005
+ queryKey: string;
1006
+ refViewNames: ReadonlySet<string>;
1007
+ type: string;
1008
+ viewSignature: string;
1009
+ }>;
1010
+ type ListRequestDescriptor = Readonly<{
1011
+ argsPayload: ResolvedArgsPayload | undefined;
1012
+ hasItems: boolean;
1013
+ kind: 'list';
1014
+ listKey: string;
1015
+ name: string;
1016
+ nodeRefViewNames: ReadonlySet<string>;
1017
+ plan: SelectionPlan;
1018
+ type: string;
1019
+ viewSignature: string;
1020
+ }>;
1021
+ type RequestItemDescriptor = NodeRequestDescriptor | QueryRequestDescriptor | ListRequestDescriptor;
1022
+ type RequestDescriptor = Readonly<{
1023
+ items: ReadonlyArray<RequestItemDescriptor>;
1024
+ key: string;
1025
+ }>;
1026
+ //#endregion
1027
+ //#region src/cache.d.ts
1028
+ declare class ViewDataCache {
1029
+ private readonly isEnabled;
1030
+ constructor(isEnabled?: () => boolean);
1031
+ private cache;
1032
+ private rootDependencies;
1033
+ private dependencyIndex;
1034
+ clear(): void;
1035
+ get<T extends Entity, S extends Selection<T>, V extends View<T, S>>(entityId: EntityId, view: V, ref: ViewRef<T['__typename']>): FateThenable<ViewSnapshot<T, S>> | null;
1036
+ set<T extends Entity, S extends Selection<T>, V extends View<T, S>>(entityId: EntityId, view: V, ref: ViewRef<T['__typename']>, thenable: FateThenable<ViewSnapshot<T, S>>, dependencies: ReadonlySet<EntityId>): void;
1037
+ invalidate(entityId: EntityId): void;
1038
+ private invalidateDependents;
1039
+ private delete;
1040
+ }
1041
+ //#endregion
1042
+ //#region src/store.d.ts
1043
+ type List = Readonly<{
1044
+ backwardPageLimit?: number;
1045
+ cursors?: ReadonlyArray<string | undefined>;
1046
+ forwardPageLimit?: number;
1047
+ ids: ReadonlyArray<EntityId>;
1048
+ liveAfterIds?: ReadonlyArray<EntityId>;
1049
+ liveBeforeIds?: ReadonlyArray<EntityId>;
1050
+ pagination?: Pagination;
1051
+ pendingAfterIds?: ReadonlyArray<EntityId>;
1052
+ pendingBeforeIds?: ReadonlyArray<EntityId>;
1053
+ }>;
1054
+ type StoreHydrationState = Readonly<{
1055
+ coverage: ReadonlyArray<readonly [EntityId, ReadonlyArray<string>]>;
1056
+ lists: ReadonlyArray<readonly [string, List]>;
1057
+ records: ReadonlyArray<readonly [EntityId, AnyRecord]>;
1058
+ }>;
1059
+ type StoreChange = Readonly<{
1060
+ key: string;
1061
+ kind: 'list';
1062
+ previousList?: List;
1063
+ }> | Readonly<{
1064
+ key: EntityId;
1065
+ kind: 'record';
1066
+ paths?: Iterable<string>;
1067
+ referencesChanged: boolean;
1068
+ }>;
1069
+ declare class Store {
1070
+ private readonly onRebase?;
1071
+ private readonly onChange?;
1072
+ private coverage;
1073
+ private listKeysByOwnerField;
1074
+ private listKeysByReferencedEntity;
1075
+ private lists;
1076
+ private recordReferenceFields;
1077
+ private recordReferencesByTarget;
1078
+ private records;
1079
+ private subscriptions;
1080
+ private listSubscriptions;
1081
+ private readonly optimisticLayers;
1082
+ private readonly optimisticBase;
1083
+ private recordingLayer;
1084
+ private rebase;
1085
+ constructor(onRebase?: ((ids: ReadonlySet<EntityId>) => void) | undefined, onChange?: ((change: StoreChange) => void) | undefined);
1086
+ get hasOptimisticUpdates(): boolean;
1087
+ get isRebasing(): boolean;
1088
+ /** Apply a synchronous cache update beneath the pending optimistic layers. */
1089
+ update<T>(apply: () => T): T;
1090
+ private getRebaseChanges;
1091
+ /** Returns an idempotent settlement function; omit its update to roll back. */
1092
+ optimisticUpdate(apply: () => void, durable?: boolean): (commit?: () => void) => void;
1093
+ private getPendingOverlap;
1094
+ private captureRecord;
1095
+ private captureList;
1096
+ get hasTransientOptimisticUpdates(): boolean;
1097
+ getOptimisticRoots(): {
1098
+ baseRecords: AnyRecord[];
1099
+ lists: string[];
1100
+ records: string[];
1101
+ };
1102
+ /** @internal Indexed owners needed for mutation rollback. */
1103
+ getPersistenceOwners(id: EntityId): {
1104
+ lists: string[];
1105
+ records: string[];
1106
+ };
1107
+ /** @internal Read one confirmed record without copying the cache. */
1108
+ readConfirmed(id: EntityId): {
1109
+ paths: string[];
1110
+ record: AnyRecord;
1111
+ } | undefined;
1112
+ /** @internal */
1113
+ readConfirmedList(key: string): Readonly<{
1114
+ backwardPageLimit?: number;
1115
+ cursors?: ReadonlyArray<string | undefined>;
1116
+ forwardPageLimit?: number;
1117
+ ids: ReadonlyArray<EntityId>;
1118
+ liveAfterIds?: ReadonlyArray<EntityId>;
1119
+ liveBeforeIds?: ReadonlyArray<EntityId>;
1120
+ pagination?: Pagination;
1121
+ pendingAfterIds?: ReadonlyArray<EntityId>;
1122
+ pendingBeforeIds?: ReadonlyArray<EntityId>;
1123
+ }> | undefined;
1124
+ dehydrateConfirmed(): StoreHydrationState;
1125
+ dehydrate(): StoreHydrationState;
1126
+ hydrate(state: StoreHydrationState, mode: 'preserve-existing' | 'replace', options?: {
1127
+ deferNotifications?: boolean;
1128
+ }): () => void;
1129
+ private rebuildIndexes;
1130
+ read(id: EntityId): AnyRecord | undefined;
1131
+ merge(id: EntityId, partial: AnyRecord, paths: Iterable<string>): void;
1132
+ private mergeInternal;
1133
+ deleteRecord(id: EntityId): void;
1134
+ missingForSelection(id: EntityId, paths: Iterable<string>): Set<string>;
1135
+ subscribe(id: EntityId, selection: ReadonlySet<string> | null, fn: () => void): () => void;
1136
+ subscribe(id: EntityId, fn: () => void): () => void;
1137
+ private notify;
1138
+ private notifyListSubscribers;
1139
+ getList(key: string): ReadonlyArray<EntityId> | undefined;
1140
+ getListState(key: string): List | undefined;
1141
+ getListsForField(ownerId: EntityId, field: string): Array<readonly [string, List]>;
1142
+ setList(key: string, state: List): void;
1143
+ replaceListEntityId(previousId: EntityId, nextId: EntityId): void;
1144
+ restoreList(key: string, list?: List): void;
1145
+ collectGarbage(markedRecords: ReadonlySet<EntityId>, markedLists: ReadonlySet<string>, options?: {
1146
+ onRecordDeleted?: (id: EntityId) => void;
1147
+ }): {
1148
+ lists: Set<string>;
1149
+ records: Set<EntityId>;
1150
+ };
1151
+ private deleteList;
1152
+ subscribeList(key: string, fn: () => void): () => void;
1153
+ removeReferencesTo(targetId: EntityId, viewDataCache: ViewDataCache): void;
1154
+ private restore;
1155
+ private addListIndexes;
1156
+ private removeListIndexes;
1157
+ private getListReferencedEntityIds;
1158
+ private getRecordFieldReferences;
1159
+ private recordReferencesChanged;
1160
+ private addRecordFieldReferenceIndex;
1161
+ private removeRecordFieldReferenceIndex;
1162
+ private addRecordReferenceIndexes;
1163
+ private removeRecordReferenceIndexes;
1164
+ private updateRecordReferenceIndexes;
1165
+ }
1166
+ //#endregion
1167
+ //#region src/hydration.d.ts
1168
+ /** JSON-safe opaque value contained in a dehydrated fate snapshot. */
1169
+ type FateSerializedValue = null | boolean | number | string | ReadonlyArray<FateSerializedValue> | Readonly<{
1170
+ [key: string]: FateSerializedValue;
1171
+ }>;
1172
+ /** Versioned, JSON-safe durable cache snapshot produced by `FateClient.dehydrate()`. */
1173
+ declare const hydrationScopeBrand: unique symbol;
1174
+ type FateDehydratedState<Scope extends string = string> = Readonly<{
1175
+ data: FateSerializedValue;
1176
+ readonly [hydrationScopeBrand]?: Scope;
1177
+ scope: Scope;
1178
+ version: 1;
1179
+ }>;
1180
+ /** Controls how `FateClient.hydrate()` reconciles a snapshot with browser cache state. */
1181
+ type HydrateOptions = Readonly<{
1182
+ /**
1183
+ * `preserve-existing` keeps browser values and list windows when conflicts
1184
+ * occur. `replace` treats the snapshot as authoritative.
1185
+ *
1186
+ * @defaultValue 'preserve-existing'
1187
+ */
1188
+ merge?: 'preserve-existing' | 'replace';
1189
+ }>;
1190
+ /** Resource limits applied while encoding and decoding hydration snapshots. */
1191
+ type HydrationLimits = Readonly<{
1192
+ /** Maximum number of entries in any encoded array or object. */
1193
+ maxCollectionLength: number;
1194
+ /** Maximum number of encoded values in a hydration snapshot. */
1195
+ maxNodes: number;
1196
+ /** Maximum length of an encoded string, object key, or bigint payload. */
1197
+ maxStringLength: number;
1198
+ }>;
1199
+ type ClientHydrationState = Readonly<{
1200
+ rootLists: ReadonlyArray<readonly [string, ReadonlyArray<string>]>;
1201
+ rootRequests: ReadonlyArray<readonly [string, string | null]>;
1202
+ store: StoreHydrationState;
1203
+ }>;
1204
+ declare const encodeHydrationValue: (value: unknown, limits?: Partial<HydrationLimits>) => FateSerializedValue;
1205
+ //#endregion
1206
+ //#region src/operation-lifetime.d.ts
1207
+ type RetainHandle = Readonly<{
1208
+ dispose(): void;
1209
+ }>;
1210
+ //#endregion
1211
+ //#region src/client.d.ts
1212
+ /**
1213
+ * Strategy used when resolving a request.
1214
+ */
1215
+ type RequestMode =
1216
+ /** (default) Use cached data if present, otherwise fetch. */
1217
+ 'cache-first' |
1218
+ /** Show cached data immediately and refresh in the background. */
1219
+ 'stale-while-revalidate' |
1220
+ /** Always fetch from the network and ignore cached entries. */
1221
+ 'network-only';
1222
+ /**
1223
+ * Request options that affect how requests are fetched and retained.
1266
1224
  */
1267
- type RequestResult<R extends FateRoots, Q extends AnyRequest> = { [K in keyof Q]: K extends keyof R ? ListResult<Q[K], RootType<R[K]>, RootResult<R[K]>> : never; };
1268
- /** Brand used on root definitions to mark their identity in the d.ts output. */
1269
- declare const RootKind = "__fate__root";
1270
- /** Brand used on mutation definitions to mark their identity in the d.ts output. */
1271
- declare const MutationKind = "__fate__mutation";
1272
- /** Metadata describing a root query for a particular entity and result shape. */
1273
- type RootDefinition<Type extends TypeName, Result> = Readonly<{
1274
- [RootKind]: true;
1275
- type: Type;
1276
- }> & __RootResultAnchor<Result> & __RootTypeAnchor<Type>;
1277
- /** Minimal root description used for typing root maps. */
1278
- type FateRoots = Record<string, RootDefinition<TypeName, unknown>>;
1279
- /** Extracts the entity type name from a root definition. */
1280
- type RootType<R> = R extends __RootTypeAnchor<infer T> ? T : never;
1281
- /** Extracts the result type from a root definition. */
1282
- type RootResult<R> = R extends __RootResultAnchor<infer Data> ? Data : never;
1283
- /** Metadata describing a mutation for a particular entity, input, and output. */
1284
- type MutationDefinition<T extends Entity, I, R> = Readonly<{
1285
- entity: T['__typename'];
1286
- [MutationKind]: true;
1287
- }> & __MutationEntityAnchor<T> & __MutationInputAnchor<I> & __MutationResultAnchor<R>;
1288
- type MutationIdentifier<T extends Entity, I, R> = MutationDefinition<T, I, R> & Readonly<{
1289
- key: string;
1225
+ type RequestOptions = Readonly<{
1226
+ mode?: RequestMode;
1227
+ /** Override disk retention in milliseconds; only used with persistence. */
1228
+ persist?: RequestPersistenceOptions;
1290
1229
  }>;
1291
- /** Extracts the input type from a mutation definition or identifier. */
1292
- type MutationInput<M> = M extends __MutationInputAnchor<infer I> ? I : never;
1293
- /** Extracts the result type from a mutation definition or identifier. */
1294
- type MutationResult<M> = M extends __MutationResultAnchor<infer R> ? R : never;
1295
- /** Extracts the entity type from a mutation definition or identifier. */
1296
- type MutationEntity<M> = M extends __MutationEntityAnchor<infer E> ? E : never;
1297
- /** Minimal mutation description used for transport typing. */
1298
- type MutationShape = {
1299
- input: unknown;
1300
- output: unknown;
1230
+ type DeferredSnapshot<T> = Readonly<{
1231
+ coverage: ReadonlyArray<readonly [id: EntityId, paths: ReadonlySet<string>]>;
1232
+ data: T;
1233
+ }>;
1234
+ type FateClientOptions<Roots extends FateRoots, Mutations extends FateMutations, HydrationScope extends string> = {
1235
+ /**
1236
+ * Number of recently released requests to keep retained before their records
1237
+ * and lists are eligible for garbage collection.
1238
+ *
1239
+ * @defaultValue 10
1240
+ */
1241
+ gcReleaseBufferSize?: number;
1242
+ /**
1243
+ * Bounds hydration snapshot encoding and decoding work.
1244
+ */
1245
+ hydrationLimits?: Partial<HydrationLimits>;
1246
+ /**
1247
+ * Identifies snapshots compatible with this client. Change this value when
1248
+ * deploying an incompatible cache schema or separating cache namespaces.
1249
+ */
1250
+ hydrationScope?: HydrationScope;
1251
+ mutations?: Mutations;
1252
+ onLiveError?: (error: unknown) => void;
1253
+ persistence?: Persistence;
1254
+ roots: Roots;
1255
+ transport: Transport<MutationMapFromDefinitions<Mutations>>;
1256
+ types: ReadonlyArray<Omit<TypeConfig, 'getId'> & Partial<{
1257
+ getId: TypeConfig['getId'];
1258
+ }>>;
1301
1259
  };
1302
1260
  /**
1303
- * Convenience helper that maps mutation definitions to their input/output
1304
- * shapes for use by transports.
1261
+ * Core client that normalizes records, manages the view cache, and coordinates
1262
+ * data fetching.
1305
1263
  */
1306
- type MutationMapFromDefinitions<D extends FateMutations> = { [K in keyof D]: {
1307
- input: MutationInput<D[K]>;
1308
- output: MutationResult<D[K]>;
1309
- }; };
1310
- type OptimisticUpdateValue<T> = T extends ReadonlyArray<infer U> ? Array<OptimisticUpdateValue<U>> : NonNullish<T> extends AnyRecord ? OptimisticUpdate<NonNullish<T>> | Nullish<T> : NonNullish<T> | Nullish<T>;
1311
- /** Shape used to describe optimistic updates for mutations. */
1312
- type OptimisticUpdate<T> = { [K in keyof T]?: OptimisticUpdateValue<T[K]>; };
1313
- /** Promise-like value returned by cache reads that already have a resolved payload for React `use`. */
1314
- interface FateThenable<T> extends PromiseLike<T> {
1315
- status: 'fulfilled';
1316
- value: T;
1264
+ declare class FateClient<Roots extends FateRoots, Mutations extends FateMutations, HydrationScope extends string = string> {
1265
+ private readonly mutationEntities?;
1266
+ private readonly mutationMap;
1267
+ private readonly parentLists;
1268
+ private readonly rootLists;
1269
+ private readonly pending;
1270
+ private readonly pendingDeferred;
1271
+ private readonly pendingOptimisticMutations;
1272
+ private readonly optimisticEntityResolutions;
1273
+ private readonly onLiveError;
1274
+ private readonly liveSubscriptions;
1275
+ private readonly liveConnectionInvalidations;
1276
+ private readonly stableRefs;
1277
+ private readonly requests;
1278
+ private readonly requestExecutionOptions;
1279
+ private readonly rootRequests;
1280
+ private readonly stalledRequests;
1281
+ private gcPending;
1282
+ private gcScheduled;
1283
+ private pendingNetworkRequests;
1284
+ private readonly persistenceDisposal?;
1285
+ private readonly persistenceRuntime?;
1286
+ readonly store: Store;
1287
+ private readonly operationLifetime;
1288
+ private readonly hydrationLimits;
1289
+ private readonly hydrationScope;
1290
+ private readonly types;
1291
+ private readonly transport;
1292
+ private readonly viewDataCache;
1293
+ private liveConnectionInvalidationToken;
1294
+ readonly persistence?: PersistenceSession;
1295
+ readonly actions: MutationActionsFor<Mutations>;
1296
+ readonly mutations: MutationFunctionsFor<Mutations>;
1297
+ readonly roots: Roots;
1298
+ constructor(options: FateClientOptions<Roots, Mutations, HydrationScope>);
1299
+ private initializeParentLists;
1300
+ /**
1301
+ * Exports the durable normalized cache as an opaque JSON-safe value for SSR
1302
+ * transfer or persistence. Runtime requests, subscriptions, retainers, and
1303
+ * optimistic state are intentionally excluded.
1304
+ */
1305
+ dehydrate(): FateDehydratedState<HydrationScope>;
1306
+ /**
1307
+ * Restores a durable normalized cache snapshot without restoring runtime
1308
+ * request handles, retainers, subscriptions, or optimistic update state.
1309
+ * Hydrate before rendering SSR content. Replaying the same snapshot is safe.
1310
+ */
1311
+ hydrate(state: FateDehydratedState<HydrationScope>, options?: HydrateOptions): void;
1312
+ /** @internal */
1313
+ exportPersistenceState(): FateDehydratedState<HydrationScope>;
1314
+ /** @internal */
1315
+ retainPersistenceRequest(request: RequestDescriptor): Readonly<{
1316
+ dispose(): void;
1317
+ }>;
1318
+ /** @internal */
1319
+ getPersistenceScope(): HydrationScope;
1320
+ /** @internal */
1321
+ getPersistenceRootLists(type: string): Set<string>;
1322
+ /** @internal */
1323
+ getPersistenceQuery(key: string): string | null | undefined;
1324
+ /** @internal Merge a small disk read beneath optimistic layers. */
1325
+ restorePersistenceData(state: ClientHydrationState): void;
1326
+ /** @internal */
1327
+ getRetainedRequests(): readonly Readonly<{
1328
+ items: ReadonlyArray<RequestItemDescriptor>;
1329
+ key: string;
1330
+ }>[];
1331
+ /** @internal */
1332
+ restoreRetainedRequests(requests: ReadonlyArray<RequestDescriptor>): void;
1333
+ /** @internal */
1334
+ hasMutation(key: string, entity: string): boolean;
1335
+ private registerRootList;
1336
+ private applyListInsert;
1337
+ private insertIntoRootLists;
1338
+ getTypeConfig(type: string): TypeConfig;
1339
+ private getListNodeType;
1340
+ /** @internal Validates local wiring without requiring network connectivity. */
1341
+ validatePersistence(): void;
1342
+ /** @internal */
1343
+ persistMutation(command: MutationCommand): Promise<unknown>;
1344
+ /** @internal */
1345
+ assertPersistenceActive(): void;
1346
+ /** @internal */
1347
+ disposePersistence(): void;
1348
+ private requireDurableMutationTransport;
1349
+ executeMutation(key: string, input: unknown, select: Set<string>, options?: {
1350
+ args?: AnyRecord;
1351
+ identity?: MutationIdentity;
1352
+ plan?: SelectionPlan;
1353
+ }): Promise<unknown>;
1354
+ write(type: string, data: AnyRecord, select: ReadonlySet<string>, plan?: SelectionPlan, insert?: InsertPosition): string;
1355
+ deleteRecord(type: string, id: string | number): void;
1356
+ private stableRefWithViewNames;
1357
+ ref<T extends Entity>(type: T['__typename'], id: string | number, view: View<T, Selection<T>>): ViewRef<T['__typename']>;
1358
+ rootListRef(entityId: EntityId, rootView: View<any, any>): Readonly<{
1359
+ __typename: string;
1360
+ id: string | number;
1361
+ [ViewsTag]: Set<string>;
1362
+ }>;
1363
+ readView<T extends Entity, S extends Selection<T>, V extends View<T, S>>(view: V, ref: ViewRef<T['__typename']>): FateThenable<ViewSnapshot<T, S>>;
1364
+ readDeferred<T>(deferred: Deferred<T>): PromiseLike<DeferredSnapshot<T>>;
1365
+ assertLiveViewSupport(): void;
1366
+ assertLiveConnectionSupport(): void;
1367
+ subscribeLiveView<T extends Entity, S extends Selection<T>, V extends View<T, S>>(view: V, ref: ViewRef<T['__typename']>): () => void;
1368
+ subscribeLiveListView<V extends View<any, any>>(view: V, connection: ConnectionMetadata): () => void;
1369
+ private applyLiveConnectionEvent;
1370
+ private invalidateLiveConnection;
1371
+ private deleteConnectionEdge;
1372
+ private insertConnectionEdge;
1373
+ private syncNestedConnectionOwnerField;
1374
+ private getConnectionInsertIndex;
1375
+ private removeEntityFromListState;
1376
+ private mergeListState;
1377
+ registerPendingOptimisticMutation(entityId: EntityId, promise: Promise<unknown>): void;
1378
+ resolveOptimisticEntity(optimisticEntityId: EntityId, resolvedEntityId: EntityId): void;
1379
+ private getPendingOptimisticMutations;
1380
+ loadConnection<V extends View<any, any>>(view: V, connection: ConnectionMetadata, args: Record<string, unknown>, options?: {
1381
+ direction?: 'forward' | 'backward';
1382
+ }): Promise<Readonly<{
1383
+ backwardPageLimit?: number;
1384
+ cursors?: ReadonlyArray<string | undefined>;
1385
+ forwardPageLimit?: number;
1386
+ ids: ReadonlyArray<EntityId>;
1387
+ liveAfterIds?: ReadonlyArray<EntityId>;
1388
+ liveBeforeIds?: ReadonlyArray<EntityId>;
1389
+ pagination?: Pagination;
1390
+ pendingAfterIds?: ReadonlyArray<EntityId>;
1391
+ pendingBeforeIds?: ReadonlyArray<EntityId>;
1392
+ }> | undefined>;
1393
+ private loadConnectionInternal;
1394
+ request<R extends Request$1>(request: R, options?: RequestOptions): Promise<RequestResult<Roots, R>>;
1395
+ requestForRender<R extends Request$1>(request: R, options?: RequestOptions): Promise<RequestResult<Roots, R>>;
1396
+ prepareRequestForRender<R extends Request$1>(request: R, options: RequestOptions | undefined): Readonly<{
1397
+ promise: Promise<RequestResult<Roots, R>>;
1398
+ requestKey: string;
1399
+ }>;
1400
+ private requestWithDescriptor;
1401
+ releaseRequest(request: Request$1, mode: RequestMode): void;
1402
+ releaseRequestKey(requestKey: string, mode: RequestMode): void;
1403
+ retainRequestKey(requestKey: string, mode?: RequestMode): RetainHandle;
1404
+ /**
1405
+ * Keeps the records and lists reachable from a request alive until the
1406
+ * returned handle is disposed.
1407
+ *
1408
+ * `useRequest` calls this automatically while the component is mounted.
1409
+ * Use it directly for non-React request lifetimes, tests, or preloaded data
1410
+ * that must survive manual garbage collection.
1411
+ */
1412
+ retain(request: Request$1): RetainHandle;
1413
+ private scheduleGarbageCollection;
1414
+ /**
1415
+ * Removes records and lists that are not reachable from retained requests or
1416
+ * the release buffer.
1417
+ *
1418
+ * Garbage collection is scheduled automatically when retained requests are
1419
+ * released. Calling this method manually is mainly useful in tests and custom
1420
+ * memory-management flows.
1421
+ */
1422
+ gc(): void;
1423
+ private executeRequestHandle;
1424
+ private markRecordReferences;
1425
+ private hasActiveOptimisticUpdates;
1426
+ private hasPendingRequests;
1427
+ /** @internal */
1428
+ withPersistenceLifecycle<T>(request: () => Promise<T>): Promise<T>;
1429
+ trackPendingRequest<T>(request: () => Promise<T>): Promise<T>;
1430
+ private runPendingGarbageCollection;
1431
+ private handleStoreAndNetworkRequest;
1432
+ private getRootType;
1433
+ private createRequestDescriptor;
1434
+ getRequestKey(request: Request$1): string;
1435
+ private hasRootListData;
1436
+ private executeRequest;
1437
+ private hasRequestData;
1438
+ getRequestResult<R extends Request$1>(request: R): RequestResult<Roots, R>;
1439
+ private getRequestResultFromDescriptor;
1440
+ private fetchByIdAndNormalize;
1441
+ private fetchQueryAndNormalize;
1442
+ private fetchListAndNormalize;
1443
+ private writeEntity;
1444
+ private linkParentLists;
1445
+ private readViewSelection;
1446
+ private clearStalledRequestsForEntity;
1447
+ private pendingPrefix;
1448
+ private pendingKey;
1449
+ private deferredPendingKey;
1450
+ private deferredSelectionSignature;
1451
+ private hasMissingDeferredList;
1452
+ private liveSubscriptionKey;
1453
+ private liveConnectionSubscriptionKey;
1454
+ private releaseLiveSubscription;
1455
+ private reportLiveError;
1456
+ }
1457
+ declare function createClient<T extends [FateRoots, FateMutations] = [Record<never, RootDefinition<any, any>>, Record<never, MutationDefinition<any, any, any>>], HydrationScope extends string = string>(options: FateClientOptions<T[0], T[1], HydrationScope>): FateClient<T[0], T[1], HydrationScope>;
1458
+ //#endregion
1459
+ //#region src/persistence-types.d.ts
1460
+ /** Identity of one logical mutation, reused across every delivery attempt. */
1461
+ type MutationIdentity = Readonly<{
1462
+ id: string;
1463
+ /** Return an existing receipt; never execute a new mutation. */
1464
+ replayOnly?: true;
1465
+ scope: string;
1466
+ }>;
1467
+ /** A persistence integration. Implementations are imported separately from Fate core. */
1468
+ interface Persistence {
1469
+ /** @internal */
1470
+ attach(client: FateClient<any, any, any>): PersistenceRuntime;
1471
+ }
1472
+ type PersistedMutationStatus = Readonly<{
1473
+ error?: string;
1474
+ id: string;
1475
+ input: unknown;
1476
+ name: string;
1477
+ status: 'queued' | 'sending' | 'failed';
1478
+ }>;
1479
+ type PersistenceSnapshot = Readonly<{
1480
+ error?: Error;
1481
+ mutations: ReadonlyArray<PersistedMutationStatus>;
1482
+ status: 'restoring' | 'ready' | 'error' | 'disposed';
1483
+ }>;
1484
+ type RequestPersistenceOptions = Readonly<{
1485
+ maxAge: number;
1486
+ }>;
1487
+ /** User-facing observability and lifecycle of an attached persistence integration. */
1488
+ interface PersistenceSession {
1489
+ clearCache(): Promise<void>;
1490
+ discard(id: string): Promise<void>;
1491
+ dispose(): void;
1492
+ flush(): Promise<void>;
1493
+ getSnapshot(): PersistenceSnapshot;
1494
+ readonly ready: Promise<void>;
1495
+ retry(): void;
1496
+ subscribe(listener: () => void): () => void;
1497
+ }
1498
+ /** Contract used internally by Fate to drive an attached persistence session. @internal */
1499
+ interface PersistenceRuntime extends PersistenceSession {
1500
+ changed(change?: StoreChange): void;
1501
+ fetched(request: RequestDescriptor, options?: RequestPersistenceOptions): void;
1502
+ mutate(command: MutationCommand): Promise<unknown>;
1503
+ restoreRequest(request: RequestDescriptor): Promise<void>;
1504
+ /** @internal */
1505
+ used(request: RequestDescriptor, options?: RequestPersistenceOptions): void;
1317
1506
  }
1318
1507
  //#endregion
1319
1508
  //#region src/transport.d.ts
@@ -1373,6 +1562,11 @@ interface Transport<Mutations extends TransportMutations = EmptyTransportMutatio
1373
1562
  }>;
1374
1563
  fetchQuery?(proc: string, select: Iterable<string>, args?: ResolvedArgsPayload): Promise<unknown>;
1375
1564
  mutate?<K extends Extract<keyof Mutations, string>>(proc: K, input: Mutations[K]['input'], select: Set<string>): Promise<Mutations[K]['output']>;
1565
+ /**
1566
+ * Deliver through an endpoint that durably deduplicates this identity. Required
1567
+ * for persisted mutations; never falls back to ordinary mutate.
1568
+ */
1569
+ mutateDurably?<K extends Extract<keyof Mutations, string>>(proc: K, input: Mutations[K]['input'], select: Set<string>, identity: MutationIdentity): Promise<Mutations[K]['output']>;
1376
1570
  subscribeById?(type: string, id: string | number, select: Iterable<string>, args: ResolvedArgsPayload | undefined, handlers: LiveEventHandlers): () => void;
1377
1571
  subscribeConnection?(procedure: string, type: string, args: ResolvedArgsPayload | undefined, select: Iterable<string>, selectionArgs: ResolvedArgsPayload | undefined, handlers: LiveConnectionEventHandlers): () => void;
1378
1572
  }
@@ -1409,12 +1603,13 @@ type EmptyMutationResolvers<AppRouter extends AnyRouter> = Record<never, Mutatio
1409
1603
  * Builds a `Transport` backed by a tRPC client using the configured resolvers
1410
1604
  * for by-id queries, lists, and mutations.
1411
1605
  */
1412
- declare function createTRPCTransport<AppRouter extends AnyRouter, Mutations extends TRPCMutationResolvers<AppRouter> = EmptyMutationResolvers<AppRouter>>({ byId, client, lists, mutations, queries }: {
1606
+ declare function createTRPCTransport<AppRouter extends AnyRouter, Mutations extends TRPCMutationResolvers<AppRouter> = EmptyMutationResolvers<AppRouter>>({ byId, client, lists, mutateDurably, mutations, queries }: {
1413
1607
  byId: TRPCByIdResolvers<AppRouter>;
1414
1608
  client: TRPCClient<AppRouter>;
1415
1609
  lists?: TRPCListResolvers<AppRouter>;
1610
+ mutateDurably?: Transport<MutationMapFromResolvers<Mutations>>['mutateDurably'];
1416
1611
  mutations?: Mutations;
1417
1612
  queries?: TRPCQueryResolvers<AppRouter>;
1418
1613
  }): Transport<MutationMapFromResolvers<Mutations>>;
1419
1614
  //#endregion
1420
- export { HydrationLimits as $, TypeConfig as A, __FateEntityBrand as B, MutationShape as C, RequestResult as D, Request$1 as E, ViewEntityName as F, DeferredSnapshot as G, isViewTag as H, ViewRef as I, RequestOptions as J, FateClient as K, ViewSelection as L, View as M, ViewData as N, RootDefinition as O, ViewEntity as P, HydrateOptions as Q, ViewSnapshot as R, MutationResult as S, Pagination as T, FateMutations as U, __FateSelectionBrand as V, mutation as W, getSelectionPlan as X, createClient as Y, FateDehydratedState as Z, Mask as _, ConnectionRef as a, MutationIdentifier as b, Deferred as c, DeferredTag as d, List as et, Entity as f, ListItem as g, FateThenable as h, ConnectionMetadata as i, TypeName as j, Selection as k, DeferredMetadata as l, FateRoots as m, createTRPCTransport as n, QueryProcedure as nt, ConnectionTag as o, EntityId as p, RequestMode as q, AnyRecord as r, DeferTag as s, Transport as t, AnyProcedure as tt, DeferredSelection as u, MutationDefinition as v, NodesItem as w, MutationInput as x, MutationEntity as y, ViewTag as z };
1615
+ export { ViewRef as $, EntityId as A, MutationShape as B, ConnectionTag as C, DeferredSelection as D, DeferredMetadata as E, MutationDefinition as F, RootDefinition as G, Pagination as H, MutationEntity as I, TypeName as J, Selection as K, MutationIdentifier as L, FateThenable as M, ListItem as N, DeferredTag as O, Mask as P, ViewEntityName as Q, MutationInput as R, ConnectionRef as S, Deferred as T, Request$1 as U, NodesItem as V, RequestResult as W, ViewData as X, View as Y, ViewEntity as Z, encodeHydrationValue as _, Persistence as a, isViewTag as at, AnyRecord as b, RequestPersistenceOptions as c, AnyProcedure as ct, RequestMode as d, ViewSelection as et, RequestOptions as f, HydrationLimits as g, HydrateOptions as h, PersistedMutationStatus as i, __FateSelectionBrand as it, FateRoots as j, Entity as k, DeferredSnapshot as l, QueryProcedure as lt, FateDehydratedState as m, createTRPCTransport as n, ViewTag as nt, PersistenceSession as o, FateMutations as ot, createClient as p, TypeConfig as q, MutationIdentity as r, __FateEntityBrand as rt, PersistenceSnapshot as s, mutation as st, Transport as t, ViewSnapshot as tt, FateClient as u, List as v, DeferTag as w, ConnectionMetadata as x, getSelectionPlan as y, MutationResult as z };