@spoosh/core 0.1.0-beta.0 → 0.2.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.
- package/README.md +40 -7
- package/dist/index.d.mts +492 -288
- package/dist/index.d.ts +492 -288
- package/dist/index.js +211 -26
- package/dist/index.mjs +211 -26
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -176,6 +176,40 @@ type EventEmitter = {
|
|
|
176
176
|
};
|
|
177
177
|
declare function createEventEmitter(): EventEmitter;
|
|
178
178
|
|
|
179
|
+
type Subscriber = () => void;
|
|
180
|
+
type CacheEntryWithKey<TData = unknown, TError = unknown> = {
|
|
181
|
+
key: string;
|
|
182
|
+
entry: CacheEntry<TData, TError>;
|
|
183
|
+
};
|
|
184
|
+
declare function createInitialState<TData, TError>(): OperationState<TData, TError>;
|
|
185
|
+
type StateManager = {
|
|
186
|
+
createQueryKey: (params: {
|
|
187
|
+
path: string[];
|
|
188
|
+
method: string;
|
|
189
|
+
options?: unknown;
|
|
190
|
+
}) => string;
|
|
191
|
+
getCache: <TData, TError>(key: string) => CacheEntry<TData, TError> | undefined;
|
|
192
|
+
setCache: <TData, TError>(key: string, entry: Partial<CacheEntry<TData, TError>>) => void;
|
|
193
|
+
deleteCache: (key: string) => void;
|
|
194
|
+
subscribeCache: (key: string, callback: Subscriber) => () => void;
|
|
195
|
+
getCacheByTags: <TData>(tags: string[]) => CacheEntry<TData> | undefined;
|
|
196
|
+
getCacheEntriesByTags: <TData, TError>(tags: string[]) => CacheEntryWithKey<TData, TError>[];
|
|
197
|
+
getCacheEntriesBySelfTag: <TData, TError>(selfTag: string) => CacheEntryWithKey<TData, TError>[];
|
|
198
|
+
setPluginResult: (key: string, data: Record<string, unknown>) => void;
|
|
199
|
+
/** Mark all cache entries with matching tags as stale */
|
|
200
|
+
markStale: (tags: string[]) => void;
|
|
201
|
+
/** Get all cache entries */
|
|
202
|
+
getAllCacheEntries: <TData, TError>() => CacheEntryWithKey<TData, TError>[];
|
|
203
|
+
/** Get the number of cache entries */
|
|
204
|
+
getSize: () => number;
|
|
205
|
+
/** Set a pending promise for a query key (for deduplication) */
|
|
206
|
+
setPendingPromise: (key: string, promise: Promise<unknown> | undefined) => void;
|
|
207
|
+
/** Get a pending promise for a query key */
|
|
208
|
+
getPendingPromise: (key: string) => Promise<unknown> | undefined;
|
|
209
|
+
clear: () => void;
|
|
210
|
+
};
|
|
211
|
+
declare function createStateManager(): StateManager;
|
|
212
|
+
|
|
179
213
|
type OperationType = "read" | "write" | "infiniteRead";
|
|
180
214
|
type LifecyclePhase = "onMount" | "onUnmount" | "onUpdate";
|
|
181
215
|
type OperationState<TData = unknown, TError = unknown> = {
|
|
@@ -536,40 +570,6 @@ type InstanceApiContext<TApi = unknown> = {
|
|
|
536
570
|
pluginExecutor: InstancePluginExecutor;
|
|
537
571
|
};
|
|
538
572
|
|
|
539
|
-
type Subscriber = () => void;
|
|
540
|
-
type CacheEntryWithKey<TData = unknown, TError = unknown> = {
|
|
541
|
-
key: string;
|
|
542
|
-
entry: CacheEntry<TData, TError>;
|
|
543
|
-
};
|
|
544
|
-
declare function createInitialState<TData, TError>(): OperationState<TData, TError>;
|
|
545
|
-
type StateManager = {
|
|
546
|
-
createQueryKey: (params: {
|
|
547
|
-
path: string[];
|
|
548
|
-
method: string;
|
|
549
|
-
options?: unknown;
|
|
550
|
-
}) => string;
|
|
551
|
-
getCache: <TData, TError>(key: string) => CacheEntry<TData, TError> | undefined;
|
|
552
|
-
setCache: <TData, TError>(key: string, entry: Partial<CacheEntry<TData, TError>>) => void;
|
|
553
|
-
deleteCache: (key: string) => void;
|
|
554
|
-
subscribeCache: (key: string, callback: Subscriber) => () => void;
|
|
555
|
-
getCacheByTags: <TData>(tags: string[]) => CacheEntry<TData> | undefined;
|
|
556
|
-
getCacheEntriesByTags: <TData, TError>(tags: string[]) => CacheEntryWithKey<TData, TError>[];
|
|
557
|
-
getCacheEntriesBySelfTag: <TData, TError>(selfTag: string) => CacheEntryWithKey<TData, TError>[];
|
|
558
|
-
setPluginResult: (key: string, data: Record<string, unknown>) => void;
|
|
559
|
-
/** Mark all cache entries with matching tags as stale */
|
|
560
|
-
markStale: (tags: string[]) => void;
|
|
561
|
-
/** Get all cache entries */
|
|
562
|
-
getAllCacheEntries: <TData, TError>() => CacheEntryWithKey<TData, TError>[];
|
|
563
|
-
/** Get the number of cache entries */
|
|
564
|
-
getSize: () => number;
|
|
565
|
-
/** Set a pending promise for a query key (for deduplication) */
|
|
566
|
-
setPendingPromise: (key: string, promise: Promise<unknown> | undefined) => void;
|
|
567
|
-
/** Get a pending promise for a query key */
|
|
568
|
-
getPendingPromise: (key: string) => Promise<unknown> | undefined;
|
|
569
|
-
clear: () => void;
|
|
570
|
-
};
|
|
571
|
-
declare function createStateManager(): StateManager;
|
|
572
|
-
|
|
573
573
|
type PluginExecutor = {
|
|
574
574
|
/** Execute lifecycle hooks for onMount or onUnmount */
|
|
575
575
|
executeLifecycle: <TData, TError>(phase: "onMount" | "onUnmount", operationType: OperationType, context: PluginContext<TData, TError>) => Promise<void>;
|
|
@@ -583,6 +583,117 @@ type PluginExecutor = {
|
|
|
583
583
|
};
|
|
584
584
|
declare function createPluginExecutor(initialPlugins?: SpooshPlugin[]): PluginExecutor;
|
|
585
585
|
|
|
586
|
+
/**
|
|
587
|
+
* Resolves plugin option types based on the full context.
|
|
588
|
+
*
|
|
589
|
+
* This is the single entry point for all type resolution. It receives
|
|
590
|
+
* the full ResolverContext containing schema, data, error, and input types,
|
|
591
|
+
* and resolves each option key accordingly.
|
|
592
|
+
*
|
|
593
|
+
* Plugins extend PluginResolvers via declaration merging to add their own
|
|
594
|
+
* resolved option types.
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* ```ts
|
|
598
|
+
* // In your plugin's types.ts:
|
|
599
|
+
* declare module "@spoosh/core" {
|
|
600
|
+
* interface PluginResolvers<TContext> {
|
|
601
|
+
* myOption: MyResolvedType<TContext["data"]> | undefined;
|
|
602
|
+
* }
|
|
603
|
+
* }
|
|
604
|
+
*
|
|
605
|
+
* // Type resolution:
|
|
606
|
+
* type ResolvedOptions = ResolveTypes<
|
|
607
|
+
* MergePluginOptions<TPlugins>["read"],
|
|
608
|
+
* {
|
|
609
|
+
* schema: ApiSchema;
|
|
610
|
+
* data: Post[];
|
|
611
|
+
* error: Error;
|
|
612
|
+
* input: { query: { page: number }; body: never; params: never; formData: never };
|
|
613
|
+
* }
|
|
614
|
+
* >;
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
type ResolveTypes<TOptions, TContext extends ResolverContext> = {
|
|
618
|
+
[K in keyof TOptions]: K extends keyof PluginResolvers<TContext> ? PluginResolvers<TContext>[K] : TOptions[K] extends DataAwareCallback<infer R, unknown, unknown> | undefined ? DataAwareCallback<R, TContext["data"], TContext["error"]> | undefined : TOptions[K] extends DataAwareTransform<unknown, unknown> | undefined ? DataAwareTransform<TContext["data"], TContext["error"]> | undefined : TOptions[K];
|
|
619
|
+
};
|
|
620
|
+
/**
|
|
621
|
+
* Resolves schema-aware types in plugin options.
|
|
622
|
+
* This is a simplified resolver for write operations that only need schema context.
|
|
623
|
+
*/
|
|
624
|
+
type ResolveSchemaTypes<TOptions, TSchema> = ResolveTypes<TOptions, ResolverContext<TSchema>>;
|
|
625
|
+
/**
|
|
626
|
+
* Resolves plugin result types based on the options passed to the hook.
|
|
627
|
+
*
|
|
628
|
+
* This allows plugins to infer result types from the options. For example,
|
|
629
|
+
* the transform plugin can infer `transformedData` type from the response
|
|
630
|
+
* transformer's return type.
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```ts
|
|
634
|
+
* // Usage in hooks:
|
|
635
|
+
* type ResolvedResults = ResolveResultTypes<PluginResults["read"], TReadOpts>;
|
|
636
|
+
* // If TReadOpts has { transform: { response: (d) => { count: number } } }
|
|
637
|
+
* // Then transformedData will be { count: number } | undefined
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
type ResolveResultTypes<TResults, TOptions> = TResults & PluginResultResolvers<TOptions>;
|
|
641
|
+
/**
|
|
642
|
+
* Resolves instance API types with schema awareness.
|
|
643
|
+
* Maps each key in TInstanceApi to its resolved type from resolvers.
|
|
644
|
+
*
|
|
645
|
+
* Plugins extend InstanceApiResolvers via declaration merging to add their own
|
|
646
|
+
* resolved instance API types.
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```ts
|
|
650
|
+
* // In your plugin's types.ts:
|
|
651
|
+
* declare module "@spoosh/core" {
|
|
652
|
+
* interface InstanceApiResolvers<TSchema> {
|
|
653
|
+
* prefetch: PrefetchFn<TSchema>;
|
|
654
|
+
* }
|
|
655
|
+
* }
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
type ResolveInstanceApi<TInstanceApi, TSchema, TReadOptions = object> = {
|
|
659
|
+
[K in keyof TInstanceApi]: K extends keyof InstanceApiResolvers<TSchema> ? InstanceApiResolvers<TSchema>[K] : TInstanceApi[K];
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
type ExtractReadOptions<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
663
|
+
readOptions: infer R;
|
|
664
|
+
} ? R : object : object;
|
|
665
|
+
type ExtractWriteOptions<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
666
|
+
writeOptions: infer W;
|
|
667
|
+
} ? W : object : object;
|
|
668
|
+
type ExtractInfiniteReadOptions<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
669
|
+
infiniteReadOptions: infer I;
|
|
670
|
+
} ? I : object : object;
|
|
671
|
+
type ExtractReadResult<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
672
|
+
readResult: infer R;
|
|
673
|
+
} ? R : object : object;
|
|
674
|
+
type ExtractWriteResult<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
675
|
+
writeResult: infer W;
|
|
676
|
+
} ? W : object : object;
|
|
677
|
+
type ExtractInstanceApi<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
678
|
+
instanceApi: infer A;
|
|
679
|
+
} ? A : object : object;
|
|
680
|
+
type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
681
|
+
type MergePluginOptions<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = {
|
|
682
|
+
read: UnionToIntersection<ExtractReadOptions<TPlugins[number]>>;
|
|
683
|
+
write: UnionToIntersection<ExtractWriteOptions<TPlugins[number]>>;
|
|
684
|
+
infiniteRead: UnionToIntersection<ExtractInfiniteReadOptions<TPlugins[number]>>;
|
|
685
|
+
};
|
|
686
|
+
type MergePluginResults<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = {
|
|
687
|
+
read: UnionToIntersection<ExtractReadResult<TPlugins[number]>>;
|
|
688
|
+
write: UnionToIntersection<ExtractWriteResult<TPlugins[number]>>;
|
|
689
|
+
};
|
|
690
|
+
type MergePluginInstanceApi<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[], TSchema = unknown> = ResolveInstanceApi<UnionToIntersection<ExtractInstanceApi<TPlugins[number]>>, TSchema, MergePluginOptions<TPlugins>["read"]>;
|
|
691
|
+
type PluginRegistry<TPlugins extends SpooshPlugin<PluginTypeConfig>[]> = {
|
|
692
|
+
plugins: TPlugins;
|
|
693
|
+
_options: MergePluginOptions<TPlugins>;
|
|
694
|
+
};
|
|
695
|
+
declare function createPluginRegistry<TPlugins extends SpooshPlugin<PluginTypeConfig>[]>(plugins: [...TPlugins]): PluginRegistry<TPlugins>;
|
|
696
|
+
|
|
586
697
|
declare const EndpointBrand: unique symbol;
|
|
587
698
|
/**
|
|
588
699
|
* Define an API endpoint with its data, request options, and error types.
|
|
@@ -722,72 +833,6 @@ type SpooshClient<TSchema, TDefaultError = unknown, TOptionsMap = object, TParam
|
|
|
722
833
|
[K in keyof StaticPathKeys<TSchema> as K extends SchemaMethod ? never : K]: SpooshClient<TSchema[K], TDefaultError, TOptionsMap, TParamNames, TRootSchema>;
|
|
723
834
|
};
|
|
724
835
|
|
|
725
|
-
type PluginArray = readonly SpooshPlugin<PluginTypeConfig>[];
|
|
726
|
-
interface SpooshConfig<TPlugins extends PluginArray = PluginArray> {
|
|
727
|
-
baseUrl: string;
|
|
728
|
-
defaultOptions?: SpooshOptions;
|
|
729
|
-
plugins?: TPlugins;
|
|
730
|
-
}
|
|
731
|
-
type SpooshInstance<TSchema = unknown, TDefaultError = unknown, TPlugins extends PluginArray = PluginArray> = {
|
|
732
|
-
api: SpooshClient<TSchema, TDefaultError, CoreRequestOptionsBase>;
|
|
733
|
-
stateManager: StateManager;
|
|
734
|
-
eventEmitter: EventEmitter;
|
|
735
|
-
pluginExecutor: PluginExecutor;
|
|
736
|
-
config: {
|
|
737
|
-
baseUrl: string;
|
|
738
|
-
defaultOptions: SpooshOptions;
|
|
739
|
-
};
|
|
740
|
-
_types: {
|
|
741
|
-
schema: TSchema;
|
|
742
|
-
defaultError: TDefaultError;
|
|
743
|
-
plugins: TPlugins;
|
|
744
|
-
};
|
|
745
|
-
};
|
|
746
|
-
|
|
747
|
-
declare function createSpoosh<TSchema = unknown, TDefaultError = unknown, const TPlugins extends PluginArray = PluginArray>(config: SpooshConfig<TPlugins>): SpooshInstance<TSchema, TDefaultError, TPlugins>;
|
|
748
|
-
|
|
749
|
-
type SpooshClientConfig = {
|
|
750
|
-
baseUrl: string;
|
|
751
|
-
defaultOptions?: SpooshOptions;
|
|
752
|
-
middlewares?: SpooshMiddleware[];
|
|
753
|
-
};
|
|
754
|
-
/**
|
|
755
|
-
* Creates a lightweight type-safe API client for vanilla JavaScript/TypeScript usage.
|
|
756
|
-
*
|
|
757
|
-
* This is a simpler alternative to `createSpoosh` for users who don't need
|
|
758
|
-
* the full plugin system, state management, or React integration.
|
|
759
|
-
*
|
|
760
|
-
* @param config - Client configuration
|
|
761
|
-
* @returns Type-safe API client
|
|
762
|
-
*
|
|
763
|
-
* @example
|
|
764
|
-
* ```ts
|
|
765
|
-
* type ApiSchema = {
|
|
766
|
-
* posts: {
|
|
767
|
-
* $get: Endpoint<Post[]>;
|
|
768
|
-
* $post: Endpoint<Post, CreatePostBody>;
|
|
769
|
-
* _: {
|
|
770
|
-
* $get: Endpoint<Post>;
|
|
771
|
-
* $delete: Endpoint<void>;
|
|
772
|
-
* };
|
|
773
|
-
* };
|
|
774
|
-
* };
|
|
775
|
-
*
|
|
776
|
-
* type ApiError = {
|
|
777
|
-
* message: string;
|
|
778
|
-
* }
|
|
779
|
-
*
|
|
780
|
-
* const api = createClient<ApiSchema, ApiError>({
|
|
781
|
-
* baseUrl: "/api",
|
|
782
|
-
* });
|
|
783
|
-
*
|
|
784
|
-
* // Type-safe API calls
|
|
785
|
-
* const { data } = await api.posts.$get();
|
|
786
|
-
* const { data: post } = await api.posts[123].$get();
|
|
787
|
-
* ```
|
|
788
|
-
*/
|
|
789
|
-
declare function createClient<TSchema, TDefaultError = unknown>(config: SpooshClientConfig): SpooshClient<TSchema, TDefaultError>;
|
|
790
|
-
|
|
791
836
|
type QueryMethod = "$get";
|
|
792
837
|
type MutationMethod = "$post" | "$put" | "$patch" | "$delete";
|
|
793
838
|
type HasQueryMethods<TSchema> = TSchema extends object ? "$get" extends keyof TSchema ? true : TSchema extends {
|
|
@@ -860,13 +905,353 @@ type MutationOnlyClient<TSchema, TDefaultError = unknown, TOptionsMap = object,
|
|
|
860
905
|
[K in keyof StaticPathKeys<TSchema> as K extends SchemaMethod ? never : HasMutationMethods<TSchema[K]> extends true ? K : never]: MutationOnlyClient<TSchema[K], TDefaultError, TOptionsMap, TParamNames>;
|
|
861
906
|
};
|
|
862
907
|
|
|
863
|
-
|
|
864
|
-
|
|
908
|
+
type ExtractEndpointData<T> = T extends {
|
|
909
|
+
data: infer D;
|
|
910
|
+
} ? D : T extends void ? void : T;
|
|
911
|
+
type ExtractEndpointRequestOptions<T> = {
|
|
912
|
+
[K in Extract<keyof T, "query" | "body" | "params">]?: T[K];
|
|
913
|
+
};
|
|
914
|
+
type EndpointToMethod<T> = (options?: ExtractEndpointRequestOptions<T>) => Promise<SpooshResponse<ExtractEndpointData<T>, unknown, ExtractEndpointRequestOptions<T>>>;
|
|
865
915
|
/**
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
|
|
869
|
-
|
|
916
|
+
* Schema navigation helper for plugins that need type-safe API schema access.
|
|
917
|
+
*
|
|
918
|
+
* This type transforms the API schema into a navigable structure where:
|
|
919
|
+
* - Static path segments become nested properties
|
|
920
|
+
* - Dynamic segments (`_`) become index signatures
|
|
921
|
+
* - `$get` endpoints become callable method types
|
|
922
|
+
*
|
|
923
|
+
* Use this in plugin option types that need to reference API endpoints:
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* ```ts
|
|
927
|
+
* // Define your plugin's callback type
|
|
928
|
+
* type MyCallbackFn<TSchema = unknown> = (
|
|
929
|
+
* api: QuerySchemaHelper<TSchema>
|
|
930
|
+
* ) => unknown;
|
|
931
|
+
*
|
|
932
|
+
* // Usage in plugin options
|
|
933
|
+
* interface MyPluginWriteOptions {
|
|
934
|
+
* myCallback?: MyCallbackFn<unknown>;
|
|
935
|
+
* }
|
|
936
|
+
*
|
|
937
|
+
* // Register for schema resolution
|
|
938
|
+
* declare module '@spoosh/core' {
|
|
939
|
+
* interface SchemaResolvers<TSchema> {
|
|
940
|
+
* myCallback: MyCallbackFn<TSchema> | undefined;
|
|
941
|
+
* }
|
|
942
|
+
* }
|
|
943
|
+
* ```
|
|
944
|
+
*
|
|
945
|
+
* @example
|
|
946
|
+
* ```ts
|
|
947
|
+
* // User's code - paths are type-checked!
|
|
948
|
+
* trigger({
|
|
949
|
+
* myCallback: (api) => [
|
|
950
|
+
* api.posts.$get, // ✓ Valid
|
|
951
|
+
* api.users[1].$get, // ✓ Dynamic segment
|
|
952
|
+
* api.nonexistent.$get, // ✗ Type error
|
|
953
|
+
* ],
|
|
954
|
+
* });
|
|
955
|
+
* ```
|
|
956
|
+
*/
|
|
957
|
+
type QuerySchemaHelper<TSchema> = {
|
|
958
|
+
[K in keyof TSchema as K extends SchemaMethod | "_" ? never : HasQueryMethods<TSchema[K]> extends true ? K : never]: K extends keyof TSchema ? QuerySchemaHelper<TSchema[K]> : never;
|
|
959
|
+
} & {
|
|
960
|
+
[K in "$get" as K extends keyof TSchema ? K : never]: K extends keyof TSchema ? EndpointToMethod<TSchema[K]> : never;
|
|
961
|
+
} & (TSchema extends {
|
|
962
|
+
_: infer D;
|
|
963
|
+
} ? HasQueryMethods<D> extends true ? {
|
|
964
|
+
/**
|
|
965
|
+
* Dynamic path segment placeholder for routes like `/posts/:id`.
|
|
966
|
+
*
|
|
967
|
+
* @example
|
|
968
|
+
* ```ts
|
|
969
|
+
* // In plugin callback - reference the endpoint
|
|
970
|
+
* myCallback: (api) => api.posts._.$get
|
|
971
|
+
* ```
|
|
972
|
+
*/
|
|
973
|
+
_: QuerySchemaHelper<D>;
|
|
974
|
+
[key: string]: QuerySchemaHelper<D>;
|
|
975
|
+
[key: number]: QuerySchemaHelper<D>;
|
|
976
|
+
} : object : object);
|
|
977
|
+
|
|
978
|
+
type PluginArray = readonly SpooshPlugin<PluginTypeConfig>[];
|
|
979
|
+
interface SpooshConfig<TPlugins extends PluginArray = PluginArray> {
|
|
980
|
+
baseUrl: string;
|
|
981
|
+
defaultOptions?: SpooshOptions;
|
|
982
|
+
plugins?: TPlugins;
|
|
983
|
+
}
|
|
984
|
+
type SpooshInstance<TSchema = unknown, TDefaultError = unknown, TPlugins extends PluginArray = PluginArray> = {
|
|
985
|
+
api: SpooshClient<TSchema, TDefaultError, CoreRequestOptionsBase>;
|
|
986
|
+
stateManager: StateManager;
|
|
987
|
+
eventEmitter: EventEmitter;
|
|
988
|
+
pluginExecutor: PluginExecutor;
|
|
989
|
+
config: {
|
|
990
|
+
baseUrl: string;
|
|
991
|
+
defaultOptions: SpooshOptions;
|
|
992
|
+
};
|
|
993
|
+
_types: {
|
|
994
|
+
schema: TSchema;
|
|
995
|
+
defaultError: TDefaultError;
|
|
996
|
+
plugins: TPlugins;
|
|
997
|
+
};
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Class-based builder for creating Spoosh instances with type-safe plugin inference.
|
|
1002
|
+
*
|
|
1003
|
+
* @template TSchema - The API schema type defining endpoints and their types
|
|
1004
|
+
* @template TError - Default error type for all requests (defaults to unknown)
|
|
1005
|
+
* @template TPlugins - A const tuple of plugin instances for type inference (defaults to empty array)
|
|
1006
|
+
*
|
|
1007
|
+
* @example Basic usage
|
|
1008
|
+
* ```ts
|
|
1009
|
+
* const client = new Spoosh<ApiSchema, Error>('/api')
|
|
1010
|
+
* .use([cachePlugin(), retryPlugin()]);
|
|
1011
|
+
*
|
|
1012
|
+
* const { api } = client;
|
|
1013
|
+
* const response = await api.posts.$get();
|
|
1014
|
+
* ```
|
|
1015
|
+
*
|
|
1016
|
+
* @example With default options
|
|
1017
|
+
* ```ts
|
|
1018
|
+
* const client = new Spoosh<ApiSchema, Error>('/api', {
|
|
1019
|
+
* headers: { 'Authorization': 'Bearer token' }
|
|
1020
|
+
* }).use([cachePlugin()]);
|
|
1021
|
+
* ```
|
|
1022
|
+
*
|
|
1023
|
+
* @example With React hooks
|
|
1024
|
+
* ```ts
|
|
1025
|
+
* import { createReactSpoosh } from '@spoosh/react';
|
|
1026
|
+
*
|
|
1027
|
+
* const client = new Spoosh<ApiSchema, Error>('/api')
|
|
1028
|
+
* .use([cachePlugin(), retryPlugin()]);
|
|
1029
|
+
*
|
|
1030
|
+
* const { useRead, useWrite } = createReactSpoosh(client);
|
|
1031
|
+
* ```
|
|
1032
|
+
*
|
|
1033
|
+
* @since 0.1.0
|
|
1034
|
+
*/
|
|
1035
|
+
declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends PluginArray = []> {
|
|
1036
|
+
private baseUrl;
|
|
1037
|
+
private defaultOptions;
|
|
1038
|
+
private _plugins;
|
|
1039
|
+
/**
|
|
1040
|
+
* Creates a new Spoosh instance.
|
|
1041
|
+
*
|
|
1042
|
+
* @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
|
|
1043
|
+
* @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
|
|
1044
|
+
* @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* ```ts
|
|
1048
|
+
* // Simple usage
|
|
1049
|
+
* const client = new Spoosh<ApiSchema, Error>('/api');
|
|
1050
|
+
*
|
|
1051
|
+
* // With default headers
|
|
1052
|
+
* const client = new Spoosh<ApiSchema, Error>('/api', {
|
|
1053
|
+
* headers: { 'X-API-Key': 'secret' }
|
|
1054
|
+
* });
|
|
1055
|
+
* ```
|
|
1056
|
+
*/
|
|
1057
|
+
constructor(baseUrl: string, defaultOptions?: SpooshOptions, plugins?: TPlugins);
|
|
1058
|
+
/**
|
|
1059
|
+
* Adds plugins to the Spoosh instance.
|
|
1060
|
+
*
|
|
1061
|
+
* Returns a **new** Spoosh instance with updated plugin types (immutable pattern).
|
|
1062
|
+
* Each call to `.use()` replaces the previous plugins rather than adding to them.
|
|
1063
|
+
*
|
|
1064
|
+
* @template TNewPlugins - The const tuple type of the new plugins array
|
|
1065
|
+
* @param plugins - Array of plugin instances to use
|
|
1066
|
+
* @returns A new Spoosh instance with the specified plugins
|
|
1067
|
+
*
|
|
1068
|
+
* @example Single use() call
|
|
1069
|
+
* ```ts
|
|
1070
|
+
* const client = new Spoosh<Schema, Error>('/api')
|
|
1071
|
+
* .use([cachePlugin(), retryPlugin(), debouncePlugin()]);
|
|
1072
|
+
* ```
|
|
1073
|
+
*
|
|
1074
|
+
* @example Chaining use() calls (replaces plugins)
|
|
1075
|
+
* ```ts
|
|
1076
|
+
* const client1 = new Spoosh<Schema, Error>('/api')
|
|
1077
|
+
* .use([cachePlugin()]);
|
|
1078
|
+
*
|
|
1079
|
+
* // This replaces cachePlugin with retryPlugin
|
|
1080
|
+
* const client2 = client1.use([retryPlugin()]);
|
|
1081
|
+
* ```
|
|
1082
|
+
*
|
|
1083
|
+
* @example With plugin configuration
|
|
1084
|
+
* ```ts
|
|
1085
|
+
* const client = new Spoosh<Schema, Error>('/api').use([
|
|
1086
|
+
* cachePlugin({ staleTime: 5000 }),
|
|
1087
|
+
* retryPlugin({ retries: 3, retryDelay: 1000 }),
|
|
1088
|
+
* prefetchPlugin(),
|
|
1089
|
+
* ]);
|
|
1090
|
+
* ```
|
|
1091
|
+
*/
|
|
1092
|
+
use<const TNewPlugins extends PluginArray>(plugins: TNewPlugins): Spoosh<TSchema, TError, TNewPlugins>;
|
|
1093
|
+
/**
|
|
1094
|
+
* Cached instance of the underlying SpooshInstance.
|
|
1095
|
+
* Created lazily on first property access.
|
|
1096
|
+
* @private
|
|
1097
|
+
*/
|
|
1098
|
+
private _instance?;
|
|
1099
|
+
/**
|
|
1100
|
+
* Gets or creates the underlying SpooshInstance.
|
|
1101
|
+
* Uses lazy initialization for optimal performance.
|
|
1102
|
+
* @private
|
|
1103
|
+
*/
|
|
1104
|
+
private getInstance;
|
|
1105
|
+
/**
|
|
1106
|
+
* The type-safe API client for making requests.
|
|
1107
|
+
*
|
|
1108
|
+
* Provides a proxy-based interface for accessing endpoints defined in your schema.
|
|
1109
|
+
*
|
|
1110
|
+
* @example
|
|
1111
|
+
* ```ts
|
|
1112
|
+
* const client = new Spoosh<ApiSchema, Error>('/api').use([...]);
|
|
1113
|
+
* const { api } = client;
|
|
1114
|
+
*
|
|
1115
|
+
* // GET request
|
|
1116
|
+
* const { data } = await api.posts.$get();
|
|
1117
|
+
*
|
|
1118
|
+
* // POST request with body
|
|
1119
|
+
* const { data } = await api.posts.$post({ body: { title: 'Hello' } });
|
|
1120
|
+
*
|
|
1121
|
+
* // Dynamic path parameters
|
|
1122
|
+
* const { data } = await api.posts[postId].$get();
|
|
1123
|
+
* ```
|
|
1124
|
+
*/
|
|
1125
|
+
get api(): SpooshClient<TSchema, TError, CoreRequestOptionsBase>;
|
|
1126
|
+
/**
|
|
1127
|
+
* State manager for cache and state operations.
|
|
1128
|
+
*
|
|
1129
|
+
* Provides methods for managing cached data, invalidating entries, and retrieving state.
|
|
1130
|
+
*
|
|
1131
|
+
* @example
|
|
1132
|
+
* ```ts
|
|
1133
|
+
* const { stateManager } = client;
|
|
1134
|
+
*
|
|
1135
|
+
* // Get cached data
|
|
1136
|
+
* const cache = stateManager.getCache('posts.$get');
|
|
1137
|
+
*
|
|
1138
|
+
* // Invalidate cache by tag
|
|
1139
|
+
* stateManager.invalidate(['posts']);
|
|
1140
|
+
*
|
|
1141
|
+
* // Clear all cache
|
|
1142
|
+
* stateManager.clearCache();
|
|
1143
|
+
* ```
|
|
1144
|
+
*/
|
|
1145
|
+
get stateManager(): StateManager;
|
|
1146
|
+
/**
|
|
1147
|
+
* Event emitter for subscribing to refetch and invalidation events.
|
|
1148
|
+
*
|
|
1149
|
+
* Used internally by plugins and hooks to trigger re-fetches.
|
|
1150
|
+
*
|
|
1151
|
+
* @example
|
|
1152
|
+
* ```ts
|
|
1153
|
+
* const { eventEmitter } = client;
|
|
1154
|
+
*
|
|
1155
|
+
* // Subscribe to refetch events
|
|
1156
|
+
* eventEmitter.on('refetch', ({ queryKey, reason }) => {
|
|
1157
|
+
* console.log(`Refetching ${queryKey} due to ${reason}`);
|
|
1158
|
+
* });
|
|
1159
|
+
* ```
|
|
1160
|
+
*/
|
|
1161
|
+
get eventEmitter(): EventEmitter;
|
|
1162
|
+
/**
|
|
1163
|
+
* Plugin executor that manages plugin lifecycle and middleware.
|
|
1164
|
+
*
|
|
1165
|
+
* Provides access to registered plugins and their execution context.
|
|
1166
|
+
*
|
|
1167
|
+
* @example
|
|
1168
|
+
* ```ts
|
|
1169
|
+
* const { pluginExecutor } = client;
|
|
1170
|
+
*
|
|
1171
|
+
* // Get all registered plugins
|
|
1172
|
+
* const plugins = pluginExecutor.getPlugins();
|
|
1173
|
+
*
|
|
1174
|
+
* // Check if a plugin is registered
|
|
1175
|
+
* const hasCache = plugins.some(p => p.name === 'cache');
|
|
1176
|
+
* ```
|
|
1177
|
+
*/
|
|
1178
|
+
get pluginExecutor(): PluginExecutor;
|
|
1179
|
+
/**
|
|
1180
|
+
* Configuration object containing baseUrl and defaultOptions.
|
|
1181
|
+
*
|
|
1182
|
+
* @example
|
|
1183
|
+
* ```ts
|
|
1184
|
+
* const { config } = client;
|
|
1185
|
+
* console.log(config.baseUrl); // '/api'
|
|
1186
|
+
* console.log(config.defaultOptions); // { headers: {...} }
|
|
1187
|
+
* ```
|
|
1188
|
+
*/
|
|
1189
|
+
get config(): {
|
|
1190
|
+
baseUrl: string;
|
|
1191
|
+
defaultOptions: SpooshOptions;
|
|
1192
|
+
};
|
|
1193
|
+
/**
|
|
1194
|
+
* Type information carrier for generic type inference.
|
|
1195
|
+
* Used internally by TypeScript for type resolution.
|
|
1196
|
+
*
|
|
1197
|
+
* @internal
|
|
1198
|
+
*/
|
|
1199
|
+
get _types(): {
|
|
1200
|
+
schema: TSchema;
|
|
1201
|
+
defaultError: TError;
|
|
1202
|
+
plugins: TPlugins;
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
type SpooshClientConfig = {
|
|
1207
|
+
baseUrl: string;
|
|
1208
|
+
defaultOptions?: SpooshOptions;
|
|
1209
|
+
middlewares?: SpooshMiddleware[];
|
|
1210
|
+
};
|
|
1211
|
+
/**
|
|
1212
|
+
* Creates a lightweight type-safe API client for vanilla JavaScript/TypeScript usage.
|
|
1213
|
+
*
|
|
1214
|
+
* This is a simpler alternative to `Spoosh` for users who don't need
|
|
1215
|
+
* the full plugin system, state management, or React integration.
|
|
1216
|
+
*
|
|
1217
|
+
* @param config - Client configuration
|
|
1218
|
+
* @returns Type-safe API client
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* ```ts
|
|
1222
|
+
* type ApiSchema = {
|
|
1223
|
+
* posts: {
|
|
1224
|
+
* $get: Endpoint<Post[]>;
|
|
1225
|
+
* $post: Endpoint<Post, CreatePostBody>;
|
|
1226
|
+
* _: {
|
|
1227
|
+
* $get: Endpoint<Post>;
|
|
1228
|
+
* $delete: Endpoint<void>;
|
|
1229
|
+
* };
|
|
1230
|
+
* };
|
|
1231
|
+
* };
|
|
1232
|
+
*
|
|
1233
|
+
* type ApiError = {
|
|
1234
|
+
* message: string;
|
|
1235
|
+
* }
|
|
1236
|
+
*
|
|
1237
|
+
* const api = createClient<ApiSchema, ApiError>({
|
|
1238
|
+
* baseUrl: "/api",
|
|
1239
|
+
* });
|
|
1240
|
+
*
|
|
1241
|
+
* // Type-safe API calls
|
|
1242
|
+
* const { data } = await api.posts.$get();
|
|
1243
|
+
* const { data: post } = await api.posts[123].$get();
|
|
1244
|
+
* ```
|
|
1245
|
+
*/
|
|
1246
|
+
declare function createClient<TSchema, TDefaultError = unknown>(config: SpooshClientConfig): SpooshClient<TSchema, TDefaultError>;
|
|
1247
|
+
|
|
1248
|
+
declare function buildUrl(baseUrl: string, path: string[], query?: Record<string, string | number | boolean | undefined>): string;
|
|
1249
|
+
|
|
1250
|
+
/**
|
|
1251
|
+
* Generate cache tags from URL path segments.
|
|
1252
|
+
* e.g., ['posts', '1'] → ['posts', 'posts/1']
|
|
1253
|
+
*/
|
|
1254
|
+
declare function generateTags(path: string[]): string[];
|
|
870
1255
|
|
|
871
1256
|
declare function isJsonBody(body: unknown): body is Record<string, unknown> | unknown[];
|
|
872
1257
|
|
|
@@ -1046,187 +1431,6 @@ declare function createMiddleware<TData = unknown, TError = unknown>(name: strin
|
|
|
1046
1431
|
declare function applyMiddlewares<TData = unknown, TError = unknown>(context: MiddlewareContext<TData, TError>, middlewares: SpooshMiddleware<TData, TError>[], phase: MiddlewarePhase): Promise<MiddlewareContext<TData, TError>>;
|
|
1047
1432
|
declare function composeMiddlewares<TData = unknown, TError = unknown>(...middlewareLists: (SpooshMiddleware<TData, TError>[] | undefined)[]): SpooshMiddleware<TData, TError>[];
|
|
1048
1433
|
|
|
1049
|
-
/**
|
|
1050
|
-
* Resolves plugin option types based on the full context.
|
|
1051
|
-
*
|
|
1052
|
-
* This is the single entry point for all type resolution. It receives
|
|
1053
|
-
* the full ResolverContext containing schema, data, error, and input types,
|
|
1054
|
-
* and resolves each option key accordingly.
|
|
1055
|
-
*
|
|
1056
|
-
* Plugins extend PluginResolvers via declaration merging to add their own
|
|
1057
|
-
* resolved option types.
|
|
1058
|
-
*
|
|
1059
|
-
* @example
|
|
1060
|
-
* ```ts
|
|
1061
|
-
* // In your plugin's types.ts:
|
|
1062
|
-
* declare module "@spoosh/core" {
|
|
1063
|
-
* interface PluginResolvers<TContext> {
|
|
1064
|
-
* myOption: MyResolvedType<TContext["data"]> | undefined;
|
|
1065
|
-
* }
|
|
1066
|
-
* }
|
|
1067
|
-
*
|
|
1068
|
-
* // Type resolution:
|
|
1069
|
-
* type ResolvedOptions = ResolveTypes<
|
|
1070
|
-
* MergePluginOptions<TPlugins>["read"],
|
|
1071
|
-
* {
|
|
1072
|
-
* schema: ApiSchema;
|
|
1073
|
-
* data: Post[];
|
|
1074
|
-
* error: Error;
|
|
1075
|
-
* input: { query: { page: number }; body: never; params: never; formData: never };
|
|
1076
|
-
* }
|
|
1077
|
-
* >;
|
|
1078
|
-
* ```
|
|
1079
|
-
*/
|
|
1080
|
-
type ResolveTypes<TOptions, TContext extends ResolverContext> = {
|
|
1081
|
-
[K in keyof TOptions]: K extends keyof PluginResolvers<TContext> ? PluginResolvers<TContext>[K] : TOptions[K] extends DataAwareCallback<infer R, unknown, unknown> | undefined ? DataAwareCallback<R, TContext["data"], TContext["error"]> | undefined : TOptions[K] extends DataAwareTransform<unknown, unknown> | undefined ? DataAwareTransform<TContext["data"], TContext["error"]> | undefined : TOptions[K];
|
|
1082
|
-
};
|
|
1083
|
-
/**
|
|
1084
|
-
* Resolves schema-aware types in plugin options.
|
|
1085
|
-
* This is a simplified resolver for write operations that only need schema context.
|
|
1086
|
-
*/
|
|
1087
|
-
type ResolveSchemaTypes<TOptions, TSchema> = ResolveTypes<TOptions, ResolverContext<TSchema>>;
|
|
1088
|
-
/**
|
|
1089
|
-
* Resolves plugin result types based on the options passed to the hook.
|
|
1090
|
-
*
|
|
1091
|
-
* This allows plugins to infer result types from the options. For example,
|
|
1092
|
-
* the transform plugin can infer `transformedData` type from the response
|
|
1093
|
-
* transformer's return type.
|
|
1094
|
-
*
|
|
1095
|
-
* @example
|
|
1096
|
-
* ```ts
|
|
1097
|
-
* // Usage in hooks:
|
|
1098
|
-
* type ResolvedResults = ResolveResultTypes<PluginResults["read"], TReadOpts>;
|
|
1099
|
-
* // If TReadOpts has { transform: { response: (d) => { count: number } } }
|
|
1100
|
-
* // Then transformedData will be { count: number } | undefined
|
|
1101
|
-
* ```
|
|
1102
|
-
*/
|
|
1103
|
-
type ResolveResultTypes<TResults, TOptions> = TResults & PluginResultResolvers<TOptions>;
|
|
1104
|
-
/**
|
|
1105
|
-
* Resolves instance API types with schema awareness.
|
|
1106
|
-
* Maps each key in TInstanceApi to its resolved type from resolvers.
|
|
1107
|
-
*
|
|
1108
|
-
* Plugins extend InstanceApiResolvers via declaration merging to add their own
|
|
1109
|
-
* resolved instance API types.
|
|
1110
|
-
*
|
|
1111
|
-
* @example
|
|
1112
|
-
* ```ts
|
|
1113
|
-
* // In your plugin's types.ts:
|
|
1114
|
-
* declare module "@spoosh/core" {
|
|
1115
|
-
* interface InstanceApiResolvers<TSchema> {
|
|
1116
|
-
* prefetch: PrefetchFn<TSchema>;
|
|
1117
|
-
* }
|
|
1118
|
-
* }
|
|
1119
|
-
* ```
|
|
1120
|
-
*/
|
|
1121
|
-
type ResolveInstanceApi<TInstanceApi, TSchema, TReadOptions = object> = {
|
|
1122
|
-
[K in keyof TInstanceApi]: K extends keyof InstanceApiResolvers<TSchema> ? InstanceApiResolvers<TSchema>[K] : TInstanceApi[K];
|
|
1123
|
-
};
|
|
1124
|
-
|
|
1125
|
-
type ExtractReadOptions<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
1126
|
-
readOptions: infer R;
|
|
1127
|
-
} ? R : object : object;
|
|
1128
|
-
type ExtractWriteOptions<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
1129
|
-
writeOptions: infer W;
|
|
1130
|
-
} ? W : object : object;
|
|
1131
|
-
type ExtractInfiniteReadOptions<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
1132
|
-
infiniteReadOptions: infer I;
|
|
1133
|
-
} ? I : object : object;
|
|
1134
|
-
type ExtractReadResult<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
1135
|
-
readResult: infer R;
|
|
1136
|
-
} ? R : object : object;
|
|
1137
|
-
type ExtractWriteResult<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
1138
|
-
writeResult: infer W;
|
|
1139
|
-
} ? W : object : object;
|
|
1140
|
-
type ExtractInstanceApi<T> = T extends SpooshPlugin<infer Types> ? Types extends {
|
|
1141
|
-
instanceApi: infer A;
|
|
1142
|
-
} ? A : object : object;
|
|
1143
|
-
type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
1144
|
-
type MergePluginOptions<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = {
|
|
1145
|
-
read: UnionToIntersection<ExtractReadOptions<TPlugins[number]>>;
|
|
1146
|
-
write: UnionToIntersection<ExtractWriteOptions<TPlugins[number]>>;
|
|
1147
|
-
infiniteRead: UnionToIntersection<ExtractInfiniteReadOptions<TPlugins[number]>>;
|
|
1148
|
-
};
|
|
1149
|
-
type MergePluginResults<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = {
|
|
1150
|
-
read: UnionToIntersection<ExtractReadResult<TPlugins[number]>>;
|
|
1151
|
-
write: UnionToIntersection<ExtractWriteResult<TPlugins[number]>>;
|
|
1152
|
-
};
|
|
1153
|
-
type MergePluginInstanceApi<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[], TSchema = unknown> = ResolveInstanceApi<UnionToIntersection<ExtractInstanceApi<TPlugins[number]>>, TSchema, MergePluginOptions<TPlugins>["read"]>;
|
|
1154
|
-
type PluginRegistry<TPlugins extends SpooshPlugin<PluginTypeConfig>[]> = {
|
|
1155
|
-
plugins: TPlugins;
|
|
1156
|
-
_options: MergePluginOptions<TPlugins>;
|
|
1157
|
-
};
|
|
1158
|
-
declare function createPluginRegistry<TPlugins extends SpooshPlugin<PluginTypeConfig>[]>(plugins: [...TPlugins]): PluginRegistry<TPlugins>;
|
|
1159
|
-
|
|
1160
|
-
type ExtractEndpointData<T> = T extends {
|
|
1161
|
-
data: infer D;
|
|
1162
|
-
} ? D : T extends void ? void : T;
|
|
1163
|
-
type ExtractEndpointRequestOptions<T> = {
|
|
1164
|
-
[K in Extract<keyof T, "query" | "body" | "params">]?: T[K];
|
|
1165
|
-
};
|
|
1166
|
-
type EndpointToMethod<T> = (options?: ExtractEndpointRequestOptions<T>) => Promise<SpooshResponse<ExtractEndpointData<T>, unknown, ExtractEndpointRequestOptions<T>>>;
|
|
1167
|
-
/**
|
|
1168
|
-
* Schema navigation helper for plugins that need type-safe API schema access.
|
|
1169
|
-
*
|
|
1170
|
-
* This type transforms the API schema into a navigable structure where:
|
|
1171
|
-
* - Static path segments become nested properties
|
|
1172
|
-
* - Dynamic segments (`_`) become index signatures
|
|
1173
|
-
* - `$get` endpoints become callable method types
|
|
1174
|
-
*
|
|
1175
|
-
* Use this in plugin option types that need to reference API endpoints:
|
|
1176
|
-
*
|
|
1177
|
-
* @example
|
|
1178
|
-
* ```ts
|
|
1179
|
-
* // Define your plugin's callback type
|
|
1180
|
-
* type MyCallbackFn<TSchema = unknown> = (
|
|
1181
|
-
* api: QuerySchemaHelper<TSchema>
|
|
1182
|
-
* ) => unknown;
|
|
1183
|
-
*
|
|
1184
|
-
* // Usage in plugin options
|
|
1185
|
-
* interface MyPluginWriteOptions {
|
|
1186
|
-
* myCallback?: MyCallbackFn<unknown>;
|
|
1187
|
-
* }
|
|
1188
|
-
*
|
|
1189
|
-
* // Register for schema resolution
|
|
1190
|
-
* declare module '@spoosh/core' {
|
|
1191
|
-
* interface SchemaResolvers<TSchema> {
|
|
1192
|
-
* myCallback: MyCallbackFn<TSchema> | undefined;
|
|
1193
|
-
* }
|
|
1194
|
-
* }
|
|
1195
|
-
* ```
|
|
1196
|
-
*
|
|
1197
|
-
* @example
|
|
1198
|
-
* ```ts
|
|
1199
|
-
* // User's code - paths are type-checked!
|
|
1200
|
-
* trigger({
|
|
1201
|
-
* myCallback: (api) => [
|
|
1202
|
-
* api.posts.$get, // ✓ Valid
|
|
1203
|
-
* api.users[1].$get, // ✓ Dynamic segment
|
|
1204
|
-
* api.nonexistent.$get, // ✗ Type error
|
|
1205
|
-
* ],
|
|
1206
|
-
* });
|
|
1207
|
-
* ```
|
|
1208
|
-
*/
|
|
1209
|
-
type QuerySchemaHelper<TSchema> = {
|
|
1210
|
-
[K in keyof TSchema as K extends SchemaMethod | "_" ? never : HasQueryMethods<TSchema[K]> extends true ? K : never]: K extends keyof TSchema ? QuerySchemaHelper<TSchema[K]> : never;
|
|
1211
|
-
} & {
|
|
1212
|
-
[K in "$get" as K extends keyof TSchema ? K : never]: K extends keyof TSchema ? EndpointToMethod<TSchema[K]> : never;
|
|
1213
|
-
} & (TSchema extends {
|
|
1214
|
-
_: infer D;
|
|
1215
|
-
} ? HasQueryMethods<D> extends true ? {
|
|
1216
|
-
/**
|
|
1217
|
-
* Dynamic path segment placeholder for routes like `/posts/:id`.
|
|
1218
|
-
*
|
|
1219
|
-
* @example
|
|
1220
|
-
* ```ts
|
|
1221
|
-
* // In plugin callback - reference the endpoint
|
|
1222
|
-
* myCallback: (api) => api.posts._.$get
|
|
1223
|
-
* ```
|
|
1224
|
-
*/
|
|
1225
|
-
_: QuerySchemaHelper<D>;
|
|
1226
|
-
[key: string]: QuerySchemaHelper<D>;
|
|
1227
|
-
[key: number]: QuerySchemaHelper<D>;
|
|
1228
|
-
} : object : object);
|
|
1229
|
-
|
|
1230
1434
|
type ExecuteOptions = {
|
|
1231
1435
|
force?: boolean;
|
|
1232
1436
|
};
|
|
@@ -1315,4 +1519,4 @@ type CreateInfiniteReadOptions<TData, TItem, TError, TRequest> = {
|
|
|
1315
1519
|
};
|
|
1316
1520
|
declare function createInfiniteReadController<TData, TItem, TError, TRequest extends InfiniteRequestOptions = InfiniteRequestOptions>(options: CreateInfiniteReadOptions<TData, TItem, TError, TRequest>): InfiniteReadController<TData, TItem, TError>;
|
|
1317
1521
|
|
|
1318
|
-
export { type AnyRequestOptions, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type Endpoint, type EventEmitter, type ExtractBody, type ExtractData, type ExtractError, type ExtractFormData, type ExtractMethodDef, type ExtractMethodOptions, type ExtractQuery, type ExtractUrlEncoded, type FetchDirection, type FetchExecutor, HTTP_METHODS, type HasMethod, type HasQueryMethods, type HasRequiredOptions, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodFn, type MethodOptionsMap, type MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, type MutationOnlyClient, type NormalizeEndpoint, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type QueryOnlyClient, type QuerySchemaHelper, type RefetchEvent, type RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type RetryConfig, type SchemaMethod, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshPlugin, type SpooshResponse, type StateManager, type StaticPathKeys, type TagOptions, applyMiddlewares, buildUrl, composeMiddlewares, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy,
|
|
1522
|
+
export { type AnyRequestOptions, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type Endpoint, type EventEmitter, type ExtractBody, type ExtractData, type ExtractError, type ExtractFormData, type ExtractMethodDef, type ExtractMethodOptions, type ExtractQuery, type ExtractUrlEncoded, type FetchDirection, type FetchExecutor, HTTP_METHODS, type HasMethod, type HasQueryMethods, type HasRequiredOptions, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodFn, type MethodOptionsMap, type MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, type MutationOnlyClient, type NormalizeEndpoint, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type QueryOnlyClient, type QuerySchemaHelper, type RefetchEvent, type RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type RetryConfig, type SchemaMethod, type SelectedEndpoint, type SelectorFunction, type SelectorResult, Spoosh, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshPlugin, type SpooshResponse, type StateManager, type StaticPathKeys, type TagOptions, applyMiddlewares, buildUrl, composeMiddlewares, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, generateTags, isJsonBody, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveTags, setHeaders, sortObjectKeys };
|