@spoosh/core 0.1.0-beta.0 → 0.2.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.
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
23
  HTTP_METHODS: () => HTTP_METHODS2,
24
+ Spoosh: () => Spoosh,
24
25
  applyMiddlewares: () => applyMiddlewares,
25
26
  buildUrl: () => buildUrl,
26
27
  composeMiddlewares: () => composeMiddlewares,
@@ -34,7 +35,6 @@ __export(src_exports, {
34
35
  createPluginRegistry: () => createPluginRegistry,
35
36
  createProxyHandler: () => createProxyHandler,
36
37
  createSelectorProxy: () => createSelectorProxy,
37
- createSpoosh: () => createSpoosh,
38
38
  createStateManager: () => createStateManager,
39
39
  executeFetch: () => executeFetch,
40
40
  extractMethodFromSelector: () => extractMethodFromSelector,
@@ -848,33 +848,218 @@ function createPluginRegistry(plugins) {
848
848
  };
849
849
  }
850
850
 
851
- // src/createSpoosh.ts
852
- function createSpoosh(config) {
853
- const {
854
- baseUrl,
855
- defaultOptions = {},
856
- plugins = []
857
- } = config;
858
- const api = createProxyHandler({ baseUrl, defaultOptions });
859
- const stateManager = createStateManager();
860
- const eventEmitter = createEventEmitter();
861
- const pluginExecutor = createPluginExecutor([...plugins]);
862
- return {
863
- api,
864
- stateManager,
865
- eventEmitter,
866
- pluginExecutor,
867
- config: {
868
- baseUrl,
869
- defaultOptions
870
- },
871
- _types: {
872
- schema: void 0,
873
- defaultError: void 0,
851
+ // src/Spoosh.ts
852
+ var Spoosh = class _Spoosh {
853
+ baseUrl;
854
+ defaultOptions;
855
+ _plugins;
856
+ /**
857
+ * Creates a new Spoosh instance.
858
+ *
859
+ * @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
860
+ * @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
861
+ * @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
862
+ *
863
+ * @example
864
+ * ```ts
865
+ * // Simple usage
866
+ * const client = new Spoosh<ApiSchema, Error>('/api');
867
+ *
868
+ * // With default headers
869
+ * const client = new Spoosh<ApiSchema, Error>('/api', {
870
+ * headers: { 'X-API-Key': 'secret' }
871
+ * });
872
+ * ```
873
+ */
874
+ constructor(baseUrl, defaultOptions, plugins) {
875
+ this.baseUrl = baseUrl;
876
+ this.defaultOptions = defaultOptions || {};
877
+ this._plugins = plugins || [];
878
+ }
879
+ /**
880
+ * Adds plugins to the Spoosh instance.
881
+ *
882
+ * Returns a **new** Spoosh instance with updated plugin types (immutable pattern).
883
+ * Each call to `.use()` replaces the previous plugins rather than adding to them.
884
+ *
885
+ * @template TNewPlugins - The const tuple type of the new plugins array
886
+ * @param plugins - Array of plugin instances to use
887
+ * @returns A new Spoosh instance with the specified plugins
888
+ *
889
+ * @example Single use() call
890
+ * ```ts
891
+ * const client = new Spoosh<Schema, Error>('/api')
892
+ * .use([cachePlugin(), retryPlugin(), debouncePlugin()]);
893
+ * ```
894
+ *
895
+ * @example Chaining use() calls (replaces plugins)
896
+ * ```ts
897
+ * const client1 = new Spoosh<Schema, Error>('/api')
898
+ * .use([cachePlugin()]);
899
+ *
900
+ * // This replaces cachePlugin with retryPlugin
901
+ * const client2 = client1.use([retryPlugin()]);
902
+ * ```
903
+ *
904
+ * @example With plugin configuration
905
+ * ```ts
906
+ * const client = new Spoosh<Schema, Error>('/api').use([
907
+ * cachePlugin({ staleTime: 5000 }),
908
+ * retryPlugin({ retries: 3, retryDelay: 1000 }),
909
+ * prefetchPlugin(),
910
+ * ]);
911
+ * ```
912
+ */
913
+ use(plugins) {
914
+ return new _Spoosh(
915
+ this.baseUrl,
916
+ this.defaultOptions,
874
917
  plugins
918
+ );
919
+ }
920
+ /**
921
+ * Cached instance of the underlying SpooshInstance.
922
+ * Created lazily on first property access.
923
+ * @private
924
+ */
925
+ _instance;
926
+ /**
927
+ * Gets or creates the underlying SpooshInstance.
928
+ * Uses lazy initialization for optimal performance.
929
+ * @private
930
+ */
931
+ getInstance() {
932
+ if (!this._instance) {
933
+ const api = createProxyHandler({
934
+ baseUrl: this.baseUrl,
935
+ defaultOptions: this.defaultOptions
936
+ });
937
+ const stateManager = createStateManager();
938
+ const eventEmitter = createEventEmitter();
939
+ const pluginExecutor = createPluginExecutor([...this._plugins]);
940
+ this._instance = {
941
+ api,
942
+ stateManager,
943
+ eventEmitter,
944
+ pluginExecutor,
945
+ config: {
946
+ baseUrl: this.baseUrl,
947
+ defaultOptions: this.defaultOptions
948
+ },
949
+ _types: {
950
+ schema: void 0,
951
+ defaultError: void 0,
952
+ plugins: this._plugins
953
+ }
954
+ };
875
955
  }
876
- };
877
- }
956
+ return this._instance;
957
+ }
958
+ /**
959
+ * The type-safe API client for making requests.
960
+ *
961
+ * Provides a proxy-based interface for accessing endpoints defined in your schema.
962
+ *
963
+ * @example
964
+ * ```ts
965
+ * const client = new Spoosh<ApiSchema, Error>('/api').use([...]);
966
+ * const { api } = client;
967
+ *
968
+ * // GET request
969
+ * const { data } = await api.posts.$get();
970
+ *
971
+ * // POST request with body
972
+ * const { data } = await api.posts.$post({ body: { title: 'Hello' } });
973
+ *
974
+ * // Dynamic path parameters
975
+ * const { data } = await api.posts[postId].$get();
976
+ * ```
977
+ */
978
+ get api() {
979
+ return this.getInstance().api;
980
+ }
981
+ /**
982
+ * State manager for cache and state operations.
983
+ *
984
+ * Provides methods for managing cached data, invalidating entries, and retrieving state.
985
+ *
986
+ * @example
987
+ * ```ts
988
+ * const { stateManager } = client;
989
+ *
990
+ * // Get cached data
991
+ * const cache = stateManager.getCache('posts.$get');
992
+ *
993
+ * // Invalidate cache by tag
994
+ * stateManager.invalidate(['posts']);
995
+ *
996
+ * // Clear all cache
997
+ * stateManager.clearCache();
998
+ * ```
999
+ */
1000
+ get stateManager() {
1001
+ return this.getInstance().stateManager;
1002
+ }
1003
+ /**
1004
+ * Event emitter for subscribing to refetch and invalidation events.
1005
+ *
1006
+ * Used internally by plugins and hooks to trigger re-fetches.
1007
+ *
1008
+ * @example
1009
+ * ```ts
1010
+ * const { eventEmitter } = client;
1011
+ *
1012
+ * // Subscribe to refetch events
1013
+ * eventEmitter.on('refetch', ({ queryKey, reason }) => {
1014
+ * console.log(`Refetching ${queryKey} due to ${reason}`);
1015
+ * });
1016
+ * ```
1017
+ */
1018
+ get eventEmitter() {
1019
+ return this.getInstance().eventEmitter;
1020
+ }
1021
+ /**
1022
+ * Plugin executor that manages plugin lifecycle and middleware.
1023
+ *
1024
+ * Provides access to registered plugins and their execution context.
1025
+ *
1026
+ * @example
1027
+ * ```ts
1028
+ * const { pluginExecutor } = client;
1029
+ *
1030
+ * // Get all registered plugins
1031
+ * const plugins = pluginExecutor.getPlugins();
1032
+ *
1033
+ * // Check if a plugin is registered
1034
+ * const hasCache = plugins.some(p => p.name === 'cache');
1035
+ * ```
1036
+ */
1037
+ get pluginExecutor() {
1038
+ return this.getInstance().pluginExecutor;
1039
+ }
1040
+ /**
1041
+ * Configuration object containing baseUrl and defaultOptions.
1042
+ *
1043
+ * @example
1044
+ * ```ts
1045
+ * const { config } = client;
1046
+ * console.log(config.baseUrl); // '/api'
1047
+ * console.log(config.defaultOptions); // { headers: {...} }
1048
+ * ```
1049
+ */
1050
+ get config() {
1051
+ return this.getInstance().config;
1052
+ }
1053
+ /**
1054
+ * Type information carrier for generic type inference.
1055
+ * Used internally by TypeScript for type resolution.
1056
+ *
1057
+ * @internal
1058
+ */
1059
+ get _types() {
1060
+ return this.getInstance()._types;
1061
+ }
1062
+ };
878
1063
 
879
1064
  // src/createClient.ts
880
1065
  function createClient(config) {
package/dist/index.mjs CHANGED
@@ -794,33 +794,218 @@ function createPluginRegistry(plugins) {
794
794
  };
795
795
  }
796
796
 
797
- // src/createSpoosh.ts
798
- function createSpoosh(config) {
799
- const {
800
- baseUrl,
801
- defaultOptions = {},
802
- plugins = []
803
- } = config;
804
- const api = createProxyHandler({ baseUrl, defaultOptions });
805
- const stateManager = createStateManager();
806
- const eventEmitter = createEventEmitter();
807
- const pluginExecutor = createPluginExecutor([...plugins]);
808
- return {
809
- api,
810
- stateManager,
811
- eventEmitter,
812
- pluginExecutor,
813
- config: {
814
- baseUrl,
815
- defaultOptions
816
- },
817
- _types: {
818
- schema: void 0,
819
- defaultError: void 0,
797
+ // src/Spoosh.ts
798
+ var Spoosh = class _Spoosh {
799
+ baseUrl;
800
+ defaultOptions;
801
+ _plugins;
802
+ /**
803
+ * Creates a new Spoosh instance.
804
+ *
805
+ * @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
806
+ * @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
807
+ * @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
808
+ *
809
+ * @example
810
+ * ```ts
811
+ * // Simple usage
812
+ * const client = new Spoosh<ApiSchema, Error>('/api');
813
+ *
814
+ * // With default headers
815
+ * const client = new Spoosh<ApiSchema, Error>('/api', {
816
+ * headers: { 'X-API-Key': 'secret' }
817
+ * });
818
+ * ```
819
+ */
820
+ constructor(baseUrl, defaultOptions, plugins) {
821
+ this.baseUrl = baseUrl;
822
+ this.defaultOptions = defaultOptions || {};
823
+ this._plugins = plugins || [];
824
+ }
825
+ /**
826
+ * Adds plugins to the Spoosh instance.
827
+ *
828
+ * Returns a **new** Spoosh instance with updated plugin types (immutable pattern).
829
+ * Each call to `.use()` replaces the previous plugins rather than adding to them.
830
+ *
831
+ * @template TNewPlugins - The const tuple type of the new plugins array
832
+ * @param plugins - Array of plugin instances to use
833
+ * @returns A new Spoosh instance with the specified plugins
834
+ *
835
+ * @example Single use() call
836
+ * ```ts
837
+ * const client = new Spoosh<Schema, Error>('/api')
838
+ * .use([cachePlugin(), retryPlugin(), debouncePlugin()]);
839
+ * ```
840
+ *
841
+ * @example Chaining use() calls (replaces plugins)
842
+ * ```ts
843
+ * const client1 = new Spoosh<Schema, Error>('/api')
844
+ * .use([cachePlugin()]);
845
+ *
846
+ * // This replaces cachePlugin with retryPlugin
847
+ * const client2 = client1.use([retryPlugin()]);
848
+ * ```
849
+ *
850
+ * @example With plugin configuration
851
+ * ```ts
852
+ * const client = new Spoosh<Schema, Error>('/api').use([
853
+ * cachePlugin({ staleTime: 5000 }),
854
+ * retryPlugin({ retries: 3, retryDelay: 1000 }),
855
+ * prefetchPlugin(),
856
+ * ]);
857
+ * ```
858
+ */
859
+ use(plugins) {
860
+ return new _Spoosh(
861
+ this.baseUrl,
862
+ this.defaultOptions,
820
863
  plugins
864
+ );
865
+ }
866
+ /**
867
+ * Cached instance of the underlying SpooshInstance.
868
+ * Created lazily on first property access.
869
+ * @private
870
+ */
871
+ _instance;
872
+ /**
873
+ * Gets or creates the underlying SpooshInstance.
874
+ * Uses lazy initialization for optimal performance.
875
+ * @private
876
+ */
877
+ getInstance() {
878
+ if (!this._instance) {
879
+ const api = createProxyHandler({
880
+ baseUrl: this.baseUrl,
881
+ defaultOptions: this.defaultOptions
882
+ });
883
+ const stateManager = createStateManager();
884
+ const eventEmitter = createEventEmitter();
885
+ const pluginExecutor = createPluginExecutor([...this._plugins]);
886
+ this._instance = {
887
+ api,
888
+ stateManager,
889
+ eventEmitter,
890
+ pluginExecutor,
891
+ config: {
892
+ baseUrl: this.baseUrl,
893
+ defaultOptions: this.defaultOptions
894
+ },
895
+ _types: {
896
+ schema: void 0,
897
+ defaultError: void 0,
898
+ plugins: this._plugins
899
+ }
900
+ };
821
901
  }
822
- };
823
- }
902
+ return this._instance;
903
+ }
904
+ /**
905
+ * The type-safe API client for making requests.
906
+ *
907
+ * Provides a proxy-based interface for accessing endpoints defined in your schema.
908
+ *
909
+ * @example
910
+ * ```ts
911
+ * const client = new Spoosh<ApiSchema, Error>('/api').use([...]);
912
+ * const { api } = client;
913
+ *
914
+ * // GET request
915
+ * const { data } = await api.posts.$get();
916
+ *
917
+ * // POST request with body
918
+ * const { data } = await api.posts.$post({ body: { title: 'Hello' } });
919
+ *
920
+ * // Dynamic path parameters
921
+ * const { data } = await api.posts[postId].$get();
922
+ * ```
923
+ */
924
+ get api() {
925
+ return this.getInstance().api;
926
+ }
927
+ /**
928
+ * State manager for cache and state operations.
929
+ *
930
+ * Provides methods for managing cached data, invalidating entries, and retrieving state.
931
+ *
932
+ * @example
933
+ * ```ts
934
+ * const { stateManager } = client;
935
+ *
936
+ * // Get cached data
937
+ * const cache = stateManager.getCache('posts.$get');
938
+ *
939
+ * // Invalidate cache by tag
940
+ * stateManager.invalidate(['posts']);
941
+ *
942
+ * // Clear all cache
943
+ * stateManager.clearCache();
944
+ * ```
945
+ */
946
+ get stateManager() {
947
+ return this.getInstance().stateManager;
948
+ }
949
+ /**
950
+ * Event emitter for subscribing to refetch and invalidation events.
951
+ *
952
+ * Used internally by plugins and hooks to trigger re-fetches.
953
+ *
954
+ * @example
955
+ * ```ts
956
+ * const { eventEmitter } = client;
957
+ *
958
+ * // Subscribe to refetch events
959
+ * eventEmitter.on('refetch', ({ queryKey, reason }) => {
960
+ * console.log(`Refetching ${queryKey} due to ${reason}`);
961
+ * });
962
+ * ```
963
+ */
964
+ get eventEmitter() {
965
+ return this.getInstance().eventEmitter;
966
+ }
967
+ /**
968
+ * Plugin executor that manages plugin lifecycle and middleware.
969
+ *
970
+ * Provides access to registered plugins and their execution context.
971
+ *
972
+ * @example
973
+ * ```ts
974
+ * const { pluginExecutor } = client;
975
+ *
976
+ * // Get all registered plugins
977
+ * const plugins = pluginExecutor.getPlugins();
978
+ *
979
+ * // Check if a plugin is registered
980
+ * const hasCache = plugins.some(p => p.name === 'cache');
981
+ * ```
982
+ */
983
+ get pluginExecutor() {
984
+ return this.getInstance().pluginExecutor;
985
+ }
986
+ /**
987
+ * Configuration object containing baseUrl and defaultOptions.
988
+ *
989
+ * @example
990
+ * ```ts
991
+ * const { config } = client;
992
+ * console.log(config.baseUrl); // '/api'
993
+ * console.log(config.defaultOptions); // { headers: {...} }
994
+ * ```
995
+ */
996
+ get config() {
997
+ return this.getInstance().config;
998
+ }
999
+ /**
1000
+ * Type information carrier for generic type inference.
1001
+ * Used internally by TypeScript for type resolution.
1002
+ *
1003
+ * @internal
1004
+ */
1005
+ get _types() {
1006
+ return this.getInstance()._types;
1007
+ }
1008
+ };
824
1009
 
825
1010
  // src/createClient.ts
826
1011
  function createClient(config) {
@@ -1387,6 +1572,7 @@ function createInfiniteReadController(options) {
1387
1572
  }
1388
1573
  export {
1389
1574
  HTTP_METHODS2 as HTTP_METHODS,
1575
+ Spoosh,
1390
1576
  applyMiddlewares,
1391
1577
  buildUrl,
1392
1578
  composeMiddlewares,
@@ -1400,7 +1586,6 @@ export {
1400
1586
  createPluginRegistry,
1401
1587
  createProxyHandler,
1402
1588
  createSelectorProxy,
1403
- createSpoosh,
1404
1589
  createStateManager,
1405
1590
  executeFetch,
1406
1591
  extractMethodFromSelector,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spoosh/core",
3
- "version": "0.1.0-beta.0",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "description": "Type-safe API client with plugin middleware system",
6
6
  "keywords": [