Skip to content

Conversation

@kyleamazza
Copy link
Collaborator

This represents the full implementation history from the export-query-options-v2 branch, consolidated from a parallel development branch with different git history.

  • Add queryOptions, mutationOptions, and infiniteQueryOptions exports for React Query v5

  • Implement service getter functions accessible outside React components

  • Add global context storage for non-hook access patterns

  • Create type-safe query key builder for cache operations

  • Replace NameFactory class with modular helper functions (name-helpers.ts)

  • Extract legacy hook generation into separate methods for clarity

  • Implement consistent naming patterns across all generated functions

  • Simplify query key structure to use interface/method pattern

  • Maintain all v0.1.0 legacy hooks with @deprecated JSDoc tags

  • Keep internal functions for existing integrations

  • Preserve existing API while guiding migration to new patterns

  • Fix parameter names with special characters in query keys

  • Resolve duplicate function declarations for non-get methods

  • Correct query key parameter syntax (params || {} instead of params?)

  • Handle methods that don't start with 'get' for suspense hooks

  • Update README with comprehensive React Query v5 usage examples

  • Add step-by-step Getting Started guide

  • Document typesModule and clientModule configuration

  • Include examples for queries, mutations, and infinite queries

  • Static structure: [interfaceName, methodName, params || {}]

  • Support for type-safe cache invalidation

  • Proper handling of optional parameters

  • Consistent pattern for both legacy hooks and new exports

The implementation evolved through several iterations:

  1. Initial NameFactory class for centralized naming
  2. Migration to helper functions for better modularity
  3. Simplification of query key generation
  4. Addition of deprecation notices and migration paths
  5. Documentation and example improvements

kyleamazza-fq and others added 13 commits August 23, 2025 14:31
This represents the full implementation history from the export-query-options-v2 branch,
consolidated from a parallel development branch with different git history.

- Add queryOptions, mutationOptions, and infiniteQueryOptions exports for React Query v5
- Implement service getter functions accessible outside React components
- Add global context storage for non-hook access patterns
- Create type-safe query key builder for cache operations

- Replace NameFactory class with modular helper functions (name-helpers.ts)
- Extract legacy hook generation into separate methods for clarity
- Implement consistent naming patterns across all generated functions
- Simplify query key structure to use interface/method pattern

- Maintain all v0.1.0 legacy hooks with @deprecated JSDoc tags
- Keep internal functions for existing integrations
- Preserve existing API while guiding migration to new patterns

- Fix parameter names with special characters in query keys
- Resolve duplicate function declarations for non-get methods
- Correct query key parameter syntax (params || {} instead of params?)
- Handle methods that don't start with 'get' for suspense hooks

- Update README with comprehensive React Query v5 usage examples
- Add step-by-step Getting Started guide
- Document typesModule and clientModule configuration
- Include examples for queries, mutations, and infinite queries

- Static structure: [interfaceName, methodName, params || {}]
- Support for type-safe cache invalidation
- Proper handling of optional parameters
- Consistent pattern for both legacy hooks and new exports

The implementation evolved through several iterations:
1. Initial NameFactory class for centralized naming
2. Migration to helper functions for better modularity
3. Simplification of query key generation
4. Addition of deprecation notices and migration paths
5. Documentation and example improvements
…ped hooks

BREAKING CHANGE: Primary exports are now query/mutation/infinite options functions rather than wrapped hooks. Legacy hooks are still available but marked as deprecated.

## Major Changes

### New Query/Mutation Options Exports
- Added direct exports for queryOptions, mutationOptions, and infiniteQueryOptions
- These follow React Query v5's recommended pattern for better tree-shaking and composability
- Example: `getWidgetsQueryOptions()` returns options for use with `useQuery()`/`useSuspenseQuery()`

### Simplified Query Key Structure
- Changed from complex path-based keys (e.g., `/widgets/${id}`) to simple array pattern
- New format: `[serviceName, methodName, params, optionalMetadata]`
- Consistent pattern for all query types (standard, infinite, mutations)
- Better cache invalidation with simpler service-level invalidation

### Deprecated Legacy Hooks
- All existing wrapped hooks (useWidgets, useSuspenseWidgets, etc.) marked with @deprecated
- Still functional for backward compatibility but will be removed in next major version
- Added deprecation notices directing users to new options exports

## Implementation Details

### Modified Files

**src/hook-file.ts**
- Added generateQueryOptionsExport() for exporting queryOptions
- Added generateMutationOptionsExport() for exporting mutationOptions
- Added generateInfiniteQueryOptionsExport() for exporting infiniteQueryOptions
- Updated buildQueryKey() to use simplified key structure
- Removed buildResourceKey() - no longer needed with simplified keys
- Added buildSimpleQueryKey() for new key pattern
- Legacy hooks now marked with @deprecated JSDoc comments

**src/name-helpers.ts**
- Migrated from NameFactory class to standalone functions
- Added buildHookName() with service parameter
- Added buildServiceGetterName() for context getter functions
- Exported all naming functions for consistency

**src/context-file.ts**
- Updated interface to extend options type with optional fetch
- Sorted interfaces alphabetically for consistent output
- Updated to use name-helpers functions instead of NameFactory

**src/hook-generator.ts & src/readme-file.ts**
- Replaced NameFactory usage with name-helpers functions
- Updated imports and function calls throughout

**src/query-key-builder.ts**
- Fixed type error with isRequired() parameter access
- Now correctly accesses parameter.value for type checking

**src/snapshot/test-utils.ts**
- Removed debug console.log statements
- Switched to @basketry/ir parser for proper service loading

## Benefits

1. **Better Tree-Shaking**: Unused hooks won't be included in bundles
2. **Composability**: Options can be modified before passing to hooks
3. **Type Safety**: Full TypeScript support with proper generic types
4. **React Query v5 Alignment**: Follows latest best practices
5. **Simpler Cache Management**: Easier query invalidation patterns

## Migration Guide

Before:
```typescript
const { data } = useWidgets({ status: 'active' });
```

After:
```typescript
const { data } = useQuery(getWidgetsQueryOptions({ status: 'active' }));
```

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
tsc doesn't work due to lacking the other generated folders necessary
for type checking
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
interface: int,
hookName: this.nameFactory.buildHookName(method),
suspenseHookName: this.nameFactory.buildHookName(method, {
hookName: buildHookName(method, this.service),
Copy link
Collaborator Author

@kyleamazza kyleamazza Aug 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ended up sort of muddled within the changes, but early on I took out the nameFactory and replaced it with regular functions, mostly on the fact that not every method in the NameFactory actually needs both the service and options (clearing out some passthrough parameters for parts of the code that call these methods)

I can change this back though, I'm pretty ambivalent to either way and don't necessarily want to introduce change for the sake of change, seeing as it doesn't necessarily add much outside of a minor clarity on params dependencies.

for (const engine of engines) {
engine.runParser();
engine.runGenerators();
await engine.runParser();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added await here since I wasn't seeing any snapshots be generated otherwise.

Each query hook is the equivalent of the general `useQuery` hook with the method-specific `queryFn`, `select`, and `queryKey` properties provided.

```tsx
import { useGizmos } from './v1/hooks/gizmos';
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Need to update with the new options usage instead.

},
"include": ["src"],
"exclude": ["**/*.test?.*"]
"exclude": ["**/*.test?.*", "src/snapshot/**/*"]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we've talked about wanting this to be buildable/type-checkable, but I'm not sure how to get this into that sort of state: namely, the generated snapshots have a dependency on @tanstack/react-query and the generated relative imports aren't matching up with what is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants