@sudobility/sudojo_client 0.0.104 → 0.0.106

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.
@@ -9,7 +9,7 @@ export { useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteB
9
9
  export { useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, } from "./use-sudojo-dailies";
10
10
  export { useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, } from "./use-sudojo-challenges";
11
11
  export { useSudojoUser, useSudojoUserSubscription } from "./use-sudojo-users";
12
- export { useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, } from "./use-sudojo-practices";
12
+ export { useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoRegeneratePracticeHints, useSudojoPracticeCounts, useSudojoRandomPractice, } from "./use-sudojo-practices";
13
13
  export { useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, } from "./use-sudojo-gamification";
14
14
  export { useSudojoInvalidation } from "./use-sudojo-invalidation";
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -8,7 +8,7 @@ export { useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteB
8
8
  export { useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, } from "./use-sudojo-dailies";
9
9
  export { useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, } from "./use-sudojo-challenges";
10
10
  export { useSudojoUser, useSudojoUserSubscription } from "./use-sudojo-users";
11
- export { useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, } from "./use-sudojo-practices";
11
+ export { useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoRegeneratePracticeHints, useSudojoPracticeCounts, useSudojoRandomPractice, } from "./use-sudojo-practices";
12
12
  export { useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, } from "./use-sudojo-gamification";
13
13
  export { useSudojoInvalidation } from "./use-sudojo-invalidation";
14
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["/**\n * Sudojo API hooks for React\n */\n\n// ============================================================================\n// Query utilities\n// ============================================================================\n\nexport { createQueryKey, getServiceKeys, queryKeys } from \"./query-keys\";\nexport type { QueryKey } from \"./query-keys\";\nexport { STALE_TIMES } from \"./query-config\";\n\n// ============================================================================\n// Health hook\n// ============================================================================\n\nexport { useSudojoHealth } from \"./use-sudojo-health\";\n\n// ============================================================================\n// Level hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n} from \"./use-sudojo-levels\";\n\n// ============================================================================\n// Technique hooks\n// ============================================================================\n\nexport {\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n} from \"./use-sudojo-techniques\";\n\n// ============================================================================\n// Learning hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n} from \"./use-sudojo-learning\";\n\n// ============================================================================\n// Board hooks\n// ============================================================================\n\nexport {\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n} from \"./use-sudojo-boards\";\n\n// ============================================================================\n// Daily hooks\n// ============================================================================\n\nexport {\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n} from \"./use-sudojo-dailies\";\n\n// ============================================================================\n// Challenge hooks\n// ============================================================================\n\nexport {\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n} from \"./use-sudojo-challenges\";\n\n// ============================================================================\n// User hooks\n// ============================================================================\n\nexport { useSudojoUser, useSudojoUserSubscription } from \"./use-sudojo-users\";\n\n// ============================================================================\n// Practice hooks\n// ============================================================================\n\nexport {\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n} from \"./use-sudojo-practices\";\n\n// ============================================================================\n// Gamification hooks (points, badges, levels, game sessions)\n// ============================================================================\n\nexport {\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n} from \"./use-sudojo-gamification\";\n\n// ============================================================================\n// Invalidation utilities\n// ============================================================================\n\nexport { useSudojoInvalidation } from \"./use-sudojo-invalidation\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAM7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["/**\n * Sudojo API hooks for React\n */\n\n// ============================================================================\n// Query utilities\n// ============================================================================\n\nexport { createQueryKey, getServiceKeys, queryKeys } from \"./query-keys\";\nexport type { QueryKey } from \"./query-keys\";\nexport { STALE_TIMES } from \"./query-config\";\n\n// ============================================================================\n// Health hook\n// ============================================================================\n\nexport { useSudojoHealth } from \"./use-sudojo-health\";\n\n// ============================================================================\n// Level hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n} from \"./use-sudojo-levels\";\n\n// ============================================================================\n// Technique hooks\n// ============================================================================\n\nexport {\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n} from \"./use-sudojo-techniques\";\n\n// ============================================================================\n// Learning hooks\n// ============================================================================\n\nexport {\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n} from \"./use-sudojo-learning\";\n\n// ============================================================================\n// Board hooks\n// ============================================================================\n\nexport {\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n} from \"./use-sudojo-boards\";\n\n// ============================================================================\n// Daily hooks\n// ============================================================================\n\nexport {\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n} from \"./use-sudojo-dailies\";\n\n// ============================================================================\n// Challenge hooks\n// ============================================================================\n\nexport {\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n} from \"./use-sudojo-challenges\";\n\n// ============================================================================\n// User hooks\n// ============================================================================\n\nexport { useSudojoUser, useSudojoUserSubscription } from \"./use-sudojo-users\";\n\n// ============================================================================\n// Practice hooks\n// ============================================================================\n\nexport {\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoRegeneratePracticeHints,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n} from \"./use-sudojo-practices\";\n\n// ============================================================================\n// Gamification hooks (points, badges, levels, game sessions)\n// ============================================================================\n\nexport {\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n} from \"./use-sudojo-gamification\";\n\n// ============================================================================\n// Invalidation utilities\n// ============================================================================\n\nexport { useSudojoInvalidation } from \"./use-sudojo-invalidation\";\n"]}
@@ -1,6 +1,6 @@
1
1
  import { UseMutationResult, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
2
2
  import type { NetworkClient } from "@sudobility/types";
3
- import type { BaseResponse, TechniquePractice, TechniquePracticeCountItem, TechniquePracticeCreateRequest } from "@sudobility/sudojo_types";
3
+ import type { BaseResponse, PracticesRegenerateHintsData, TechniquePractice, TechniquePracticeCountItem, TechniquePracticeCreateRequest } from "@sudobility/sudojo_types";
4
4
  export declare const useSudojoPracticeCounts: (networkClient: NetworkClient, baseUrl: string, token: string, options?: Omit<UseQueryOptions<BaseResponse<TechniquePracticeCountItem[]>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<TechniquePracticeCountItem[]>>;
5
5
  export declare const useSudojoRandomPractice: (networkClient: NetworkClient, baseUrl: string, token: string, technique: number, options?: Omit<UseQueryOptions<BaseResponse<TechniquePractice>>, "queryKey" | "queryFn">) => UseQueryResult<BaseResponse<TechniquePractice>>;
6
6
  export declare const useSudojoCreatePractice: (networkClient: NetworkClient, baseUrl: string) => UseMutationResult<BaseResponse<TechniquePractice>, Error, {
@@ -13,4 +13,7 @@ export declare const useSudojoDeleteAllPractices: (networkClient: NetworkClient,
13
13
  }>, Error, {
14
14
  token: string;
15
15
  }>;
16
+ export declare const useSudojoRegeneratePracticeHints: (networkClient: NetworkClient, baseUrl: string) => UseMutationResult<BaseResponse<PracticesRegenerateHintsData>, Error, {
17
+ token: string;
18
+ }>;
16
19
  //# sourceMappingURL=use-sudojo-practices.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-sudojo-practices.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sudojo-practices.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,iBAAiB,EAGjB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,0BAA0B,EAC1B,8BAA8B,EAC/B,MAAM,0BAA0B,CAAC;AAgBlC,eAAO,MAAM,uBAAuB,GAClC,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CACZ,eAAe,CAAC,YAAY,CAAC,0BAA0B,EAAE,CAAC,CAAC,EAC3D,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,0BAA0B,EAAE,CAAC,CAqB3D,CAAC;AAeF,eAAO,MAAM,uBAAuB,GAClC,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,WAAW,MAAM,EACjB,UAAU,IAAI,CACZ,eAAe,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAChD,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAsBhD,CAAC;AAWF,eAAO,MAAM,uBAAuB,GAClC,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,iBAAiB,CAAC,EAC/B,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,8BAA8B,CAAA;CAAE,CAwBxD,CAAC;AAaF,eAAO,MAAM,2BAA2B,GACtC,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAkBlB,CAAC"}
1
+ {"version":3,"file":"use-sudojo-practices.d.ts","sourceRoot":"","sources":["../../src/hooks/use-sudojo-practices.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,iBAAiB,EAGjB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,4BAA4B,EAC5B,iBAAiB,EACjB,0BAA0B,EAC1B,8BAA8B,EAC/B,MAAM,0BAA0B,CAAC;AAgBlC,eAAO,MAAM,uBAAuB,GAClC,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAU,IAAI,CACZ,eAAe,CAAC,YAAY,CAAC,0BAA0B,EAAE,CAAC,CAAC,EAC3D,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,0BAA0B,EAAE,CAAC,CAqB3D,CAAC;AAeF,eAAO,MAAM,uBAAuB,GAClC,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,WAAW,MAAM,EACjB,UAAU,IAAI,CACZ,eAAe,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,EAChD,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAsBhD,CAAC;AAWF,eAAO,MAAM,uBAAuB,GAClC,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,iBAAiB,CAAC,EAC/B,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,8BAA8B,CAAA;CAAE,CAwBxD,CAAC;AAaF,eAAO,MAAM,2BAA2B,GACtC,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAkBlB,CAAC;AAEF,eAAO,MAAM,gCAAgC,GAC3C,eAAe,aAAa,EAC5B,SAAS,MAAM,KACd,iBAAiB,CAClB,YAAY,CAAC,4BAA4B,CAAC,EAC1C,KAAK,EACL;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAYlB,CAAC"}
@@ -58,4 +58,12 @@ export const useSudojoDeleteAllPractices = (networkClient, baseUrl) => {
58
58
  },
59
59
  });
60
60
  };
61
+ export const useSudojoRegeneratePracticeHints = (networkClient, baseUrl) => {
62
+ const client = useMemo(() => new SudojoClient(networkClient, baseUrl), [networkClient, baseUrl]);
63
+ return useMutation({
64
+ mutationFn: async ({ token }) => {
65
+ return client.regeneratePracticeHints(token);
66
+ },
67
+ });
68
+ };
61
69
  //# sourceMappingURL=use-sudojo-practices.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-sudojo-practices.js","sourceRoot":"","sources":["../../src/hooks/use-sudojo-practices.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hook for Sudojo practices endpoints\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport {\n useMutation,\n UseMutationResult,\n useQuery,\n useQueryClient,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { NetworkClient } from \"@sudobility/types\";\nimport type {\n BaseResponse,\n TechniquePractice,\n TechniquePracticeCountItem,\n TechniquePracticeCreateRequest,\n} from \"@sudobility/sudojo_types\";\nimport { queryKeys } from \"./query-keys\";\nimport { SudojoClient } from \"../network/sudojo-client\";\n\n/**\n * Hook to fetch practice counts for all techniques.\n *\n * Returns the number of practice puzzles available for each technique.\n * Uses `staleTime: 0` to always fetch fresh counts.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing an array of TechniquePracticeCountItem\n */\nexport const useSudojoPracticeCounts = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<\n UseQueryOptions<BaseResponse<TechniquePracticeCountItem[]>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<TechniquePracticeCountItem[]>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<\n BaseResponse<TechniquePracticeCountItem[]>\n > => {\n return client.getPracticeCounts(token);\n }, [client, token]);\n\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.practiceCounts(),\n queryFn,\n staleTime: 0, // Always fetch fresh for counts\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a random practice puzzle for a specific technique.\n *\n * The query is automatically disabled when technique < 1. Uses `staleTime: 0`\n * to always fetch a fresh random practice.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token\n * @param technique - Technique number (>= 1). Query is disabled if < 1.\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing a single TechniquePractice object\n */\nexport const useSudojoRandomPractice = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n technique: number,\n options?: Omit<\n UseQueryOptions<BaseResponse<TechniquePractice>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<TechniquePractice>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<\n BaseResponse<TechniquePractice>\n > => {\n return client.getRandomPractice(token, technique);\n }, [client, token, technique]);\n\n const isEnabled =\n technique >= 1 && (options?.enabled !== undefined ? options.enabled : true);\n\n return useQuery({\n queryKey: queryKeys.sudojo.practiceRandom(technique),\n queryFn,\n staleTime: 0, // Always fetch fresh for random\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to create a new practice puzzle. **Admin only.**\n *\n * On success, invalidates the practice counts query so the UI reflects the new count.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, data })` to execute.\n */\nexport const useSudojoCreatePractice = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<TechniquePractice>,\n Error,\n { token: string; data: TechniquePracticeCreateRequest }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({\n token,\n data,\n }: {\n token: string;\n data: TechniquePracticeCreateRequest;\n }) => {\n return client.createPractice(token, data);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: queryKeys.sudojo.practiceCounts(),\n });\n },\n });\n};\n\n/**\n * Hook to delete all practices. **Admin only.** This is a destructive operation\n * that removes all practice puzzles from the database.\n *\n * Internally passes `confirm=true` as a query parameter (required by the API\n * as a safety measure). On success, invalidates the practice counts query.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token })` to execute.\n */\nexport const useSudojoDeleteAllPractices = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<{ deleted: number; message: string }>,\n Error,\n { token: string }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ token }: { token: string }) => {\n return client.deleteAllPractices(token);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: queryKeys.sudojo.practiceCounts(),\n });\n },\n });\n};\n"]}
1
+ {"version":3,"file":"use-sudojo-practices.js","sourceRoot":"","sources":["../../src/hooks/use-sudojo-practices.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hook for Sudojo practices endpoints\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport {\n useMutation,\n UseMutationResult,\n useQuery,\n useQueryClient,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { NetworkClient } from \"@sudobility/types\";\nimport type {\n BaseResponse,\n PracticesRegenerateHintsData,\n TechniquePractice,\n TechniquePracticeCountItem,\n TechniquePracticeCreateRequest,\n} from \"@sudobility/sudojo_types\";\nimport { queryKeys } from \"./query-keys\";\nimport { SudojoClient } from \"../network/sudojo-client\";\n\n/**\n * Hook to fetch practice counts for all techniques.\n *\n * Returns the number of practice puzzles available for each technique.\n * Uses `staleTime: 0` to always fetch fresh counts.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing an array of TechniquePracticeCountItem\n */\nexport const useSudojoPracticeCounts = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options?: Omit<\n UseQueryOptions<BaseResponse<TechniquePracticeCountItem[]>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<TechniquePracticeCountItem[]>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<\n BaseResponse<TechniquePracticeCountItem[]>\n > => {\n return client.getPracticeCounts(token);\n }, [client, token]);\n\n const isEnabled = options?.enabled !== undefined ? options.enabled : true;\n\n return useQuery({\n queryKey: queryKeys.sudojo.practiceCounts(),\n queryFn,\n staleTime: 0, // Always fetch fresh for counts\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to fetch a random practice puzzle for a specific technique.\n *\n * The query is automatically disabled when technique < 1. Uses `staleTime: 0`\n * to always fetch a fresh random practice.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @param token - Firebase access token\n * @param technique - Technique number (>= 1). Query is disabled if < 1.\n * @param options - Additional TanStack Query options\n * @returns A UseQueryResult containing a single TechniquePractice object\n */\nexport const useSudojoRandomPractice = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n technique: number,\n options?: Omit<\n UseQueryOptions<BaseResponse<TechniquePractice>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<TechniquePractice>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<\n BaseResponse<TechniquePractice>\n > => {\n return client.getRandomPractice(token, technique);\n }, [client, token, technique]);\n\n const isEnabled =\n technique >= 1 && (options?.enabled !== undefined ? options.enabled : true);\n\n return useQuery({\n queryKey: queryKeys.sudojo.practiceRandom(technique),\n queryFn,\n staleTime: 0, // Always fetch fresh for random\n ...options,\n enabled: isEnabled,\n });\n};\n\n/**\n * Hook to create a new practice puzzle. **Admin only.**\n *\n * On success, invalidates the practice counts query so the UI reflects the new count.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token, data })` to execute.\n */\nexport const useSudojoCreatePractice = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<TechniquePractice>,\n Error,\n { token: string; data: TechniquePracticeCreateRequest }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({\n token,\n data,\n }: {\n token: string;\n data: TechniquePracticeCreateRequest;\n }) => {\n return client.createPractice(token, data);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: queryKeys.sudojo.practiceCounts(),\n });\n },\n });\n};\n\n/**\n * Hook to delete all practices. **Admin only.** This is a destructive operation\n * that removes all practice puzzles from the database.\n *\n * Internally passes `confirm=true` as a query parameter (required by the API\n * as a safety measure). On success, invalidates the practice counts query.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL of the Sudojo API\n * @returns A UseMutationResult. Call `mutate({ token })` to execute.\n */\nexport const useSudojoDeleteAllPractices = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<{ deleted: number; message: string }>,\n Error,\n { token: string }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ token }: { token: string }) => {\n return client.deleteAllPractices(token);\n },\n onSuccess: () => {\n queryClient.invalidateQueries({\n queryKey: queryKeys.sudojo.practiceCounts(),\n });\n },\n });\n};\n\nexport const useSudojoRegeneratePracticeHints = (\n networkClient: NetworkClient,\n baseUrl: string,\n): UseMutationResult<\n BaseResponse<PracticesRegenerateHintsData>,\n Error,\n { token: string }\n> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n return useMutation({\n mutationFn: async ({ token }: { token: string }) => {\n return client.regeneratePracticeHints(token);\n },\n });\n};\n"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { configureSolutionKey, createSudojoClient, isValidUUID, SudojoClient, validateUUID, } from "./network";
2
2
  export type { GenerateOptions, SolveOptions, ValidateOptions } from "./network";
3
3
  export { HintAccessDeniedError } from "./errors";
4
- export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
4
+ export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoRegeneratePracticeHints, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
5
5
  export type { QueryKey } from "./hooks";
6
6
  export { getSolverServiceKeys, solverQueryKeys, SOLVER_STALE_TIMES, useSolverGenerate, useSolverSolve, useSolverValidate, } from "./solver";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGhF,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAGhF,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { configureSolutionKey, createSudojoClient, isValidUUID, SudojoClient, validateUUID, } from "./network";
2
2
  export { HintAccessDeniedError } from "./errors";
3
- export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
3
+ export { createQueryKey, getServiceKeys, queryKeys, STALE_TIMES, useSudojoHealth, useSudojoCreateLevel, useSudojoDeleteLevel, useSudojoLevel, useSudojoLevels, useSudojoUpdateLevel, useSudojoCreateTechnique, useSudojoDeleteTechnique, useSudojoTechnique, useSudojoTechniques, useSudojoUpdateTechnique, useSudojoCreateLearning, useSudojoDeleteLearning, useSudojoLearning, useSudojoLearningItem, useSudojoUpdateLearning, useSudojoBoard, useSudojoBoards, useSudojoCreateBoard, useSudojoDeleteBoard, useSudojoRandomBoard, useSudojoUpdateBoard, useSudojoCreateDaily, useSudojoDailies, useSudojoDaily, useSudojoDailyByDate, useSudojoDeleteDaily, useSudojoTodayDaily, useSudojoUpdateDaily, useSudojoChallenge, useSudojoChallenges, useSudojoCreateChallenge, useSudojoDeleteChallenge, useSudojoRandomChallenge, useSudojoUpdateChallenge, useSudojoUser, useSudojoUserSubscription, useSudojoCreatePractice, useSudojoDeleteAllPractices, useSudojoRegeneratePracticeHints, useSudojoPracticeCounts, useSudojoRandomPractice, useSudojoBadgeDefinitions, useSudojoGamificationStats, useSudojoPlayFinish, useSudojoPlayStart, useSudojoPointHistory, useSudojoInvalidation, } from "./hooks";
4
4
  export { getSolverServiceKeys, solverQueryKeys, SOLVER_STALE_TIMES, useSolverGenerate, useSolverSolve, useSolverValidate, } from "./solver";
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC","sourcesContent":["// Main library exports\nexport {\n configureSolutionKey,\n createSudojoClient,\n isValidUUID,\n SudojoClient,\n validateUUID,\n} from \"./network\";\nexport type { GenerateOptions, SolveOptions, ValidateOptions } from \"./network\";\n\n// Errors\nexport { HintAccessDeniedError } from \"./errors\";\n\n// React hooks\nexport {\n // Query utilities\n createQueryKey,\n getServiceKeys,\n queryKeys,\n STALE_TIMES,\n // Health\n useSudojoHealth,\n // Levels\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n // Techniques\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n // Learning\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n // Boards\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n // Dailies\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n // Challenges\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n // Users\n useSudojoUser,\n useSudojoUserSubscription,\n // Practices\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n // Gamification\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n // Invalidation utilities\n useSudojoInvalidation,\n} from \"./hooks\";\nexport type { QueryKey } from \"./hooks\";\n\n// Solver hooks\nexport {\n getSolverServiceKeys,\n solverQueryKeys,\n SOLVER_STALE_TIMES,\n useSolverGenerate,\n useSolverSolve,\n useSolverValidate,\n} from \"./solver\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGjD,OAAO,EAEL,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EAEX,eAAe,EAEf,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,oBAAoB,EAEpB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EAEvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EAEpB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EAEpB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EAExB,aAAa,EACb,yBAAyB,EAEzB,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,uBAAuB,EACvB,uBAAuB,EAEvB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAIjB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,UAAU,CAAC","sourcesContent":["// Main library exports\nexport {\n configureSolutionKey,\n createSudojoClient,\n isValidUUID,\n SudojoClient,\n validateUUID,\n} from \"./network\";\nexport type { GenerateOptions, SolveOptions, ValidateOptions } from \"./network\";\n\n// Errors\nexport { HintAccessDeniedError } from \"./errors\";\n\n// React hooks\nexport {\n // Query utilities\n createQueryKey,\n getServiceKeys,\n queryKeys,\n STALE_TIMES,\n // Health\n useSudojoHealth,\n // Levels\n useSudojoCreateLevel,\n useSudojoDeleteLevel,\n useSudojoLevel,\n useSudojoLevels,\n useSudojoUpdateLevel,\n // Techniques\n useSudojoCreateTechnique,\n useSudojoDeleteTechnique,\n useSudojoTechnique,\n useSudojoTechniques,\n useSudojoUpdateTechnique,\n // Learning\n useSudojoCreateLearning,\n useSudojoDeleteLearning,\n useSudojoLearning,\n useSudojoLearningItem,\n useSudojoUpdateLearning,\n // Boards\n useSudojoBoard,\n useSudojoBoards,\n useSudojoCreateBoard,\n useSudojoDeleteBoard,\n useSudojoRandomBoard,\n useSudojoUpdateBoard,\n // Dailies\n useSudojoCreateDaily,\n useSudojoDailies,\n useSudojoDaily,\n useSudojoDailyByDate,\n useSudojoDeleteDaily,\n useSudojoTodayDaily,\n useSudojoUpdateDaily,\n // Challenges\n useSudojoChallenge,\n useSudojoChallenges,\n useSudojoCreateChallenge,\n useSudojoDeleteChallenge,\n useSudojoRandomChallenge,\n useSudojoUpdateChallenge,\n // Users\n useSudojoUser,\n useSudojoUserSubscription,\n // Practices\n useSudojoCreatePractice,\n useSudojoDeleteAllPractices,\n useSudojoRegeneratePracticeHints,\n useSudojoPracticeCounts,\n useSudojoRandomPractice,\n // Gamification\n useSudojoBadgeDefinitions,\n useSudojoGamificationStats,\n useSudojoPlayFinish,\n useSudojoPlayStart,\n useSudojoPointHistory,\n // Invalidation utilities\n useSudojoInvalidation,\n} from \"./hooks\";\nexport type { QueryKey } from \"./hooks\";\n\n// Solver hooks\nexport {\n getSolverServiceKeys,\n solverQueryKeys,\n SOLVER_STALE_TIMES,\n useSolverGenerate,\n useSolverSolve,\n useSolverValidate,\n} from \"./solver\";\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { NetworkClient, UserInfoResponse } from "@sudobility/types";
2
- import { type BadgeDefinition, type BaseResponse, type Board, type BoardCountsByTechniqueData, type BoardCountsData, type BoardCreateRequest, type BoardQueryParams, type BoardUpdateRequest, type Challenge, type ChallengeCreateRequest, type ChallengeQueryParams, type ChallengeUpdateRequest, type Daily, type DailyCreateRequest, type DailyUpdateRequest, type ExampleCountsData, type GameFinishRequest, type GameFinishResponse, type GameStartRequest, type GameStartResponse, type GamificationStats, type GenerateData, type GenerateOptions, type HealthCheckData, isValidUUID, type Learning, type LearningCreateRequest, type LearningQueryParams, type LearningUpdateRequest, type Level, type LevelCreateRequest, type LevelUpdateRequest, type PointTransaction, type PracticesBulkDeleteData, type SolveData, type SolveOptions, type SubscriptionResult, type Technique, type TechniqueCreateRequest, type TechniqueExample, type TechniqueExampleCreateRequest, type TechniqueExampleQueryParams, type TechniquePractice, type TechniquePracticeCountItem, type TechniquePracticeCreateRequest, type TechniqueQueryParams, type TechniqueUpdateRequest, type UpdateStatsData, type ValidateData, type ValidateOptions, validateUUID } from "@sudobility/sudojo_types";
2
+ import { type BadgeDefinition, type BaseResponse, type Board, type BoardCountsByTechniqueData, type BoardCountsData, type BoardCreateRequest, type BoardQueryParams, type BoardUpdateRequest, type Challenge, type ChallengeCreateRequest, type ChallengeQueryParams, type ChallengeUpdateRequest, type Daily, type DailyCreateRequest, type DailyUpdateRequest, type ExampleCountsData, type GameFinishRequest, type GameFinishResponse, type GameStartRequest, type GameStartResponse, type GamificationStats, type GenerateData, type GenerateOptions, type HealthCheckData, isValidUUID, type Learning, type LearningCreateRequest, type LearningQueryParams, type LearningUpdateRequest, type Level, type LevelCreateRequest, type LevelUpdateRequest, type PointTransaction, type PracticesBulkDeleteData, type PracticesRegenerateHintsData, type SolveData, type SolveOptions, type SubscriptionResult, type Technique, type TechniqueCreateRequest, type TechniqueExample, type TechniqueExampleCreateRequest, type TechniqueExampleQueryParams, type TechniquePractice, type TechniquePracticeCountItem, type TechniquePracticeCreateRequest, type TechniqueQueryParams, type TechniqueUpdateRequest, type UpdateStatsData, type ValidateData, type ValidateOptions, validateUUID } from "@sudobility/sudojo_types";
3
3
  export type { SolveOptions, ValidateOptions, GenerateOptions };
4
4
  export declare function configureSolutionKey(keyHex: string): Promise<void>;
5
5
  export declare class SudojoClient {
@@ -50,6 +50,7 @@ export declare class SudojoClient {
50
50
  getRandomPractice(token: string, technique: number): Promise<BaseResponse<TechniquePractice>>;
51
51
  createPractice(token: string, data: TechniquePracticeCreateRequest): Promise<BaseResponse<TechniquePractice>>;
52
52
  deleteAllPractices(token: string): Promise<BaseResponse<PracticesBulkDeleteData>>;
53
+ regeneratePracticeHints(token: string): Promise<BaseResponse<PracticesRegenerateHintsData>>;
53
54
  getExampleCounts(token: string): Promise<BaseResponse<ExampleCountsData>>;
54
55
  getExamples(token: string, queryParams?: TechniqueExampleQueryParams): Promise<BaseResponse<TechniqueExample[]>>;
55
56
  createExample(token: string, data: TechniqueExampleCreateRequest): Promise<BaseResponse<TechniqueExample>>;
@@ -1 +1 @@
1
- {"version":3,"file":"sudojo-client.d.ts","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sudojo-client.d.ts","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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"}
@@ -449,6 +449,12 @@ export class SudojoClient {
449
449
  token,
450
450
  });
451
451
  }
452
+ async regeneratePracticeHints(token) {
453
+ return this.request(`${this.config.ENDPOINTS.PRACTICES}/regenerate-hints`, {
454
+ method: "POST",
455
+ token,
456
+ });
457
+ }
452
458
  async getExampleCounts(token) {
453
459
  return this.request(this.config.ENDPOINTS.EXAMPLES_COUNTS, { token });
454
460
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sudojo-client.js","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NetworkClient, UserInfoResponse } from \"@sudobility/types\";\nimport {\n type BadgeDefinition,\n type BaseResponse,\n type Board,\n type BoardCountsByTechniqueData,\n type BoardCountsData,\n type BoardCreateRequest,\n type BoardQueryParams,\n type BoardUpdateRequest,\n type Challenge,\n type ChallengeCreateRequest,\n type ChallengeQueryParams,\n type ChallengeUpdateRequest,\n type Daily,\n type DailyCreateRequest,\n type DailyUpdateRequest,\n type ExampleCountsData,\n type GameFinishRequest,\n type GameFinishResponse,\n type GameStartRequest,\n type GameStartResponse,\n type GamificationStats,\n type GenerateData,\n type GenerateOptions,\n type HealthCheckData,\n type HintAccessDeniedResponse,\n isValidUUID,\n type Learning,\n type LearningCreateRequest,\n type LearningQueryParams,\n type LearningUpdateRequest,\n type Level,\n type LevelCreateRequest,\n type LevelUpdateRequest,\n type Optional,\n type PointTransaction,\n type PracticesBulkDeleteData,\n type SolveData,\n type SolveOptions,\n type SubscriptionResult,\n type Technique,\n type TechniqueCreateRequest,\n type TechniqueExample,\n type TechniqueExampleCreateRequest,\n type TechniqueExampleQueryParams,\n type TechniquePractice,\n type TechniquePracticeCountItem,\n type TechniquePracticeCreateRequest,\n type TechniqueQueryParams,\n type TechniqueUpdateRequest,\n type UpdateStatsData,\n type ValidateData,\n type ValidateOptions,\n validateUUID,\n} from \"@sudobility/sudojo_types\";\nimport { HintAccessDeniedError } from \"../errors\";\n\n// Re-export option types for convenience\nexport type { SolveOptions, ValidateOptions, GenerateOptions };\n\n// =============================================================================\n// Solution Decryption\n// =============================================================================\n\nlet _solutionKey: CryptoKey | null = null;\n\n/**\n * Configure the symmetric key used to decrypt `solution` fields in API responses.\n * Call once at app startup with the hex-encoded 256-bit key.\n * If not called (or called with empty string), encrypted solutions pass through as-is.\n */\nexport async function configureSolutionKey(keyHex: string): Promise<void> {\n if (!keyHex) return;\n const hexPairs = keyHex.match(/.{2}/g);\n if (!hexPairs) return;\n const keyBytes = new Uint8Array(hexPairs.map((byte) => parseInt(byte, 16)));\n _solutionKey = await globalThis.crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n \"AES-GCM\",\n false,\n [\"decrypt\"],\n );\n}\n\nasync function decryptSolution(encrypted: string): Promise<string> {\n if (!_solutionKey) return encrypted;\n\n const raw = globalThis.atob(encrypted.slice(4)); // strip \"enc:\" prefix\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n\n const nonce = bytes.slice(0, 12);\n const ciphertextWithTag = bytes.slice(12);\n\n const decrypted = await globalThis.crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: nonce },\n _solutionKey,\n ciphertextWithTag,\n );\n\n return new TextDecoder().decode(decrypted);\n}\n\nasync function decryptSolutionFields(data: unknown): Promise<unknown> {\n if (data === null || data === undefined) return data;\n\n if (Array.isArray(data)) {\n return Promise.all(data.map((item) => decryptSolutionFields(item)));\n }\n\n if (typeof data === \"object\") {\n const obj = data as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n if (\n key === \"solution\" &&\n typeof obj[key] === \"string\" &&\n (obj[key] as string).startsWith(\"enc:\")\n ) {\n result[key] = await decryptSolution(obj[key] as string);\n } else {\n result[key] = await decryptSolutionFields(obj[key]);\n }\n }\n return result;\n }\n\n return data;\n}\n\n// =============================================================================\n// URL Search Params Utility\n// =============================================================================\n\n/**\n * Creates a lightweight URL search params builder.\n *\n * This is a custom implementation instead of the standard `URLSearchParams`\n * because the solver API requires a special encoding behavior: **commas must\n * NOT be percent-encoded** in pencilmark values. The standard `URLSearchParams`\n * encodes commas as `%2C`, which the Kotlin-based solver backend does not decode.\n *\n * @returns An object with `append(key, value)` and `toString()` methods\n *\n * @example\n * ```ts\n * const params = createURLSearchParams();\n * params.append(\"pencilmarks\", \"1,2,3\");\n * params.toString(); // \"pencilmarks=1,2,3\" (commas preserved)\n * ```\n */\nconst createURLSearchParams = () => {\n const params: Record<string, string[]> = {};\n return {\n append: (key: string, value: string) => {\n if (!params[key]) {\n params[key] = [];\n }\n params[key]?.push(value);\n },\n toString: () => {\n return Object.entries(params)\n .flatMap(([key, values]) =>\n values.map(\n (value) =>\n // Don't encode commas - the solver API expects literal commas in pencilmarks\n `${encodeURIComponent(key)}=${encodeURIComponent(value).replace(/%2C/g, \",\")}`,\n ),\n )\n .join(\"&\");\n },\n };\n};\n\n// =============================================================================\n// API Configuration Factory\n// =============================================================================\n\nconst createApiConfig = (baseUrl: string) => ({\n BASE_URL: baseUrl,\n ENDPOINTS: {\n // Health\n HEALTH: \"/\",\n\n // Levels\n LEVELS: \"/api/v1/levels\",\n LEVEL: (level: number) => `/api/v1/levels/${level}`,\n\n // Techniques\n TECHNIQUES: \"/api/v1/techniques\",\n TECHNIQUE: (technique: number) => `/api/v1/techniques/${technique}`,\n\n // Learning\n LEARNING: \"/api/v1/learning\",\n LEARNING_ITEM: (uuid: string) => `/api/v1/learning/${uuid}`,\n\n // Boards\n BOARDS: \"/api/v1/boards\",\n BOARDS_RANDOM: \"/api/v1/boards/random\",\n BOARD: (uuid: string) => `/api/v1/boards/${uuid}`,\n\n // Dailies\n DAILIES: \"/api/v1/dailies\",\n DAILIES_TODAY: \"/api/v1/dailies/today\",\n DAILIES_DATE: (date: string) => `/api/v1/dailies/date/${date}`,\n DAILY: (uuid: string) => `/api/v1/dailies/${uuid}`,\n\n // Challenges\n CHALLENGES: \"/api/v1/challenges\",\n CHALLENGES_RANDOM: \"/api/v1/challenges/random\",\n CHALLENGE: (uuid: string) => `/api/v1/challenges/${uuid}`,\n\n // Users\n USER: (userId: string) => `/api/v1/users/${userId}`,\n USER_SUBSCRIPTIONS: (userId: string) =>\n `/api/v1/users/${userId}/subscriptions`,\n\n // Solver\n SOLVER_SOLVE: \"/api/v1/solver/solve\",\n SOLVER_VALIDATE: \"/api/v1/solver/validate\",\n SOLVER_GENERATE: \"/api/v1/solver/generate\",\n\n // Practices\n PRACTICES: \"/api/v1/practices\",\n PRACTICES_COUNTS: \"/api/v1/practices/counts\",\n PRACTICE_RANDOM: (technique: number) =>\n `/api/v1/practices/technique/${technique}/random`,\n\n // Examples\n EXAMPLES: \"/api/v1/examples\",\n EXAMPLES_COUNTS: \"/api/v1/examples/counts\",\n\n // Boards counts\n BOARDS_COUNTS: \"/api/v1/boards/counts\",\n BOARDS_COUNTS_BY_TECHNIQUE: \"/api/v1/boards/counts/by-technique\",\n BOARDS_UPDATE_STATS: \"/api/v1/boards/update-stats\",\n\n // Play (game sessions)\n PLAY_START: \"/api/v1/play/start\",\n PLAY_FINISH: \"/api/v1/play/finish\",\n\n // Gamification\n GAMIFICATION_STATS: \"/api/v1/gamification/stats\",\n GAMIFICATION_BADGES: \"/api/v1/gamification/badges\",\n GAMIFICATION_HISTORY: \"/api/v1/gamification/history\",\n },\n DEFAULT_HEADERS: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n});\n\n// =============================================================================\n// Sudojo Client Class\n// =============================================================================\n\n/**\n * Type-safe client for the Sudojo REST API.\n *\n * Provides methods for all Sudojo API endpoints including levels, techniques,\n * boards, dailies, challenges, users, solver, practices, examples, and gamification.\n *\n * ## Error Handling\n *\n * All methods throw errors on failure:\n * - **Network errors**: Thrown by the underlying `NetworkClient` (e.g., connection refused, timeout)\n * - **Empty response**: Throws `Error(\"No data received from server\")` when the server returns no data\n * - **Validation errors**: Thrown before the request for invalid parameters (e.g., invalid UUID, level out of range)\n * - **HTTP 402**: `solverSolve()` throws {@link HintAccessDeniedError} when the hint level exceeds the user's tier\n * - **Other HTTP errors**: Depend on the `NetworkClient` implementation - typically thrown as generic `Error`\n *\n * ## Authentication\n *\n * Most methods accept a `token` parameter (Firebase ID token). The token is sent\n * as a `Bearer` token in the `Authorization` header. Public endpoints (health,\n * levels, boards, etc.) accept but do not require a token. User-specific endpoints\n * (subscriptions, gamification) require a valid token.\n *\n * ## Usage\n *\n * ```typescript\n * const client = new SudojoClient(networkClient, \"https://api.sudojo.com\");\n * const levels = await client.getLevels(token);\n * const daily = await client.getDailyByDate(token, \"2024-01-15\");\n * ```\n */\nexport class SudojoClient {\n private baseUrl: string;\n private headers: Record<string, string>;\n private networkClient: NetworkClient;\n private config: ReturnType<typeof createApiConfig>;\n\n /**\n * Create a SudojoClient instance.\n *\n * @param networkClient - Network client for making HTTP requests (from `@sudobility/types`)\n * @param baseUrl - Base URL for the Sudojo API (e.g., \"https://api.sudojo.com\")\n */\n constructor(networkClient: NetworkClient, baseUrl: string) {\n this.config = createApiConfig(baseUrl);\n this.baseUrl = this.config.BASE_URL;\n this.networkClient = networkClient;\n\n this.headers = {\n ...this.config.DEFAULT_HEADERS,\n };\n }\n\n // ===========================================================================\n // Private Request Method\n // ===========================================================================\n\n private async request<T>(\n endpoint: string,\n options: {\n method?: Optional<\"GET\" | \"POST\" | \"PUT\" | \"DELETE\">;\n body?: Optional<Record<string, unknown>>;\n headers?: Optional<Record<string, string>>;\n token?: Optional<string>;\n timeout?: Optional<number>;\n } = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n ...options.headers,\n };\n\n // Add authorization header if token is provided\n if (options.token) {\n requestHeaders[\"Authorization\"] = `Bearer ${options.token}`;\n }\n\n const requestOptions: {\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n headers: Record<string, string>;\n body?: string;\n timeout?: number;\n } = {\n method: options.method || \"GET\",\n headers: requestHeaders,\n };\n\n // Add body for POST/PUT/DELETE requests\n if (options.body && options.method !== \"GET\") {\n requestOptions.body = JSON.stringify(options.body);\n }\n\n // Add timeout if specified\n if (options.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await this.networkClient.request<T>(url, requestOptions);\n\n if (response.data === undefined) {\n throw new Error(\"No data received from server\");\n }\n\n return (await decryptSolutionFields(response.data)) as T;\n }\n\n // ===========================================================================\n // Health Check\n // ===========================================================================\n\n async getHealth(): Promise<BaseResponse<HealthCheckData>> {\n return this.request<BaseResponse<HealthCheckData>>(\n this.config.ENDPOINTS.HEALTH,\n );\n }\n\n // ===========================================================================\n // Levels\n // ===========================================================================\n\n async getLevels(token: string): Promise<BaseResponse<Level[]>> {\n return this.request<BaseResponse<Level[]>>(this.config.ENDPOINTS.LEVELS, {\n token,\n });\n }\n\n async getLevel(token: string, level: number): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n { token },\n );\n }\n\n async createLevel(\n token: string,\n data: LevelCreateRequest,\n ): Promise<BaseResponse<Level>> {\n return this.request<BaseResponse<Level>>(this.config.ENDPOINTS.LEVELS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateLevel(\n token: string,\n level: number,\n data: LevelUpdateRequest,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLevel(\n token: string,\n level: number,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Techniques\n // ===========================================================================\n\n async getTechniques(\n token: string,\n queryParams?: TechniqueQueryParams,\n ): Promise<BaseResponse<Technique[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.TECHNIQUES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Technique[]>>(endpoint, { token });\n }\n\n async getTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n { token },\n );\n }\n\n async createTechnique(\n token: string,\n data: TechniqueCreateRequest,\n ): Promise<BaseResponse<Technique>> {\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateTechnique(\n token: string,\n technique: number,\n data: TechniqueUpdateRequest,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Learning\n // ===========================================================================\n\n async getLearning(\n token: string,\n queryParams?: LearningQueryParams,\n ): Promise<BaseResponse<Learning[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n if (queryParams?.language_code) {\n params.append(\"language_code\", queryParams.language_code);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.LEARNING}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Learning[]>>(endpoint, { token });\n }\n\n async getLearningItem(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n { token },\n );\n }\n\n async createLearning(\n token: string,\n data: LearningCreateRequest,\n ): Promise<BaseResponse<Learning>> {\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateLearning(\n token: string,\n uuid: string,\n data: LearningUpdateRequest,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLearning(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Boards\n // ===========================================================================\n\n async getBoards(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.limit !== undefined) {\n params.append(\"limit\", String(queryParams.limit));\n }\n if (queryParams?.offset !== undefined) {\n params.append(\"offset\", String(queryParams.offset));\n }\n if (queryParams?.techniques !== undefined) {\n params.append(\"techniques\", String(queryParams.techniques));\n }\n if (queryParams?.technique_bit !== undefined) {\n params.append(\"technique_bit\", String(queryParams.technique_bit));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board[]>>(endpoint, { token });\n }\n\n async getRandomBoard(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n if (queryParams?.symmetrical !== undefined) {\n params.append(\"symmetrical\", String(queryParams.symmetrical));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board>>(endpoint, { token });\n }\n\n async getBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n { token },\n );\n }\n\n async createBoard(\n token: string,\n data: BoardCreateRequest,\n ): Promise<BaseResponse<Board>> {\n return this.request<BaseResponse<Board>>(this.config.ENDPOINTS.BOARDS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateBoard(\n token: string,\n uuid: string,\n data: BoardUpdateRequest,\n ): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Dailies\n // ===========================================================================\n\n async getDailies(token: string): Promise<BaseResponse<Daily[]>> {\n return this.request<BaseResponse<Daily[]>>(this.config.ENDPOINTS.DAILIES, {\n token,\n });\n }\n\n async getTodayDaily(token: string): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_TODAY,\n { token },\n );\n }\n\n async getDailyByDate(\n token: string,\n date: string,\n ): Promise<BaseResponse<Daily>> {\n // Validate date format (YYYY-MM-DD)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n throw new Error(\n `Invalid date format: \"${date}\". Expected YYYY-MM-DD format`,\n );\n }\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_DATE(date),\n { token },\n );\n }\n\n async getDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n { token },\n );\n }\n\n async createDaily(\n token: string,\n data: DailyCreateRequest,\n ): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(this.config.ENDPOINTS.DAILIES, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateDaily(\n token: string,\n uuid: string,\n data: DailyUpdateRequest,\n ): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Challenges\n // ===========================================================================\n\n async getChallenges(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge[]>>(endpoint, { token });\n }\n\n async getRandomChallenge(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge>>(endpoint, { token });\n }\n\n async getChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n { token },\n );\n }\n\n async createChallenge(\n token: string,\n data: ChallengeCreateRequest,\n ): Promise<BaseResponse<Challenge>> {\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateChallenge(\n token: string,\n uuid: string,\n data: ChallengeUpdateRequest,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Users\n // ===========================================================================\n\n async getUser(\n token: string,\n userId: string,\n ): Promise<BaseResponse<UserInfoResponse>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n return this.request<BaseResponse<UserInfoResponse>>(\n this.config.ENDPOINTS.USER(userId),\n {\n token,\n },\n );\n }\n\n async getUserSubscription(\n token: string,\n userId: string,\n testMode?: boolean,\n ): Promise<BaseResponse<SubscriptionResult>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n const endpoint = testMode\n ? `${this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId)}?testMode=true`\n : this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId);\n return this.request<BaseResponse<SubscriptionResult>>(endpoint, {\n token,\n });\n }\n\n // ===========================================================================\n // Practices\n // ===========================================================================\n\n /**\n * Get practice counts for all techniques\n */\n async getPracticeCounts(\n token: string,\n ): Promise<BaseResponse<TechniquePracticeCountItem[]>> {\n return this.request<BaseResponse<TechniquePracticeCountItem[]>>(\n this.config.ENDPOINTS.PRACTICES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get a random practice for a specific technique\n */\n async getRandomPractice(\n token: string,\n technique: number,\n ): Promise<BaseResponse<TechniquePractice>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICE_RANDOM(technique),\n { token },\n );\n }\n\n /**\n * Create a new practice (admin only)\n */\n async createPractice(\n token: string,\n data: TechniquePracticeCreateRequest,\n ): Promise<BaseResponse<TechniquePractice>> {\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Delete all practices (admin only, requires confirm=true)\n */\n async deleteAllPractices(\n token: string,\n ): Promise<BaseResponse<PracticesBulkDeleteData>> {\n return this.request<BaseResponse<PracticesBulkDeleteData>>(\n `${this.config.ENDPOINTS.PRACTICES}?confirm=true`,\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Examples\n // ===========================================================================\n\n /**\n * Get example counts for all techniques\n */\n async getExampleCounts(\n token: string,\n ): Promise<BaseResponse<ExampleCountsData>> {\n return this.request<BaseResponse<ExampleCountsData>>(\n this.config.ENDPOINTS.EXAMPLES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get examples, optionally filtered by technique\n */\n async getExamples(\n token: string,\n queryParams?: TechniqueExampleQueryParams,\n ): Promise<BaseResponse<TechniqueExample[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.EXAMPLES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<TechniqueExample[]>>(endpoint, { token });\n }\n\n /**\n * Create a new example (admin only)\n */\n async createExample(\n token: string,\n data: TechniqueExampleCreateRequest,\n ): Promise<BaseResponse<TechniqueExample>> {\n return this.request<BaseResponse<TechniqueExample>>(\n this.config.ENDPOINTS.EXAMPLES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Board Counts\n // ===========================================================================\n\n /**\n * Get board counts (total and without techniques)\n */\n async getBoardCounts(token: string): Promise<BaseResponse<BoardCountsData>> {\n return this.request<BaseResponse<BoardCountsData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS,\n { token },\n );\n }\n\n /**\n * Get board counts by technique (count of boards with each technique bit set)\n * Returns Record<number, number> where key is technique ID and value is count\n */\n async getBoardCountsByTechnique(\n token: string,\n ): Promise<BaseResponse<BoardCountsByTechniqueData>> {\n return this.request<BaseResponse<BoardCountsByTechniqueData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS_BY_TECHNIQUE,\n { token },\n );\n }\n\n /**\n * Calculate and update puzzle stats (percentages) on levels and techniques.\n * Requires admin authentication.\n */\n async updatePuzzleStats(\n token: string,\n ): Promise<BaseResponse<UpdateStatsData>> {\n return this.request<BaseResponse<UpdateStatsData>>(\n this.config.ENDPOINTS.BOARDS_UPDATE_STATS,\n {\n method: \"POST\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Solver\n // ===========================================================================\n\n /**\n * Builds an endpoint path with query parameters for solver endpoints\n */\n private buildSolverUrl(\n endpoint: string,\n params: Record<string, string | boolean | undefined>,\n ): string {\n const searchParams = createURLSearchParams();\n // Sort keys alphabetically to match Kotlin behavior\n const sortedKeys = Object.keys(params).sort();\n for (const key of sortedKeys) {\n const value = params[key];\n if (value !== undefined) {\n searchParams.append(key, String(value));\n }\n }\n const query = searchParams.toString();\n // Return endpoint + query only, baseUrl is added by request()\n return `${endpoint}${query ? `?${query}` : \"\"}`;\n }\n\n /**\n * Get hints for solving a Sudoku puzzle\n * @throws {HintAccessDeniedError} When hint level exceeds user's subscription tier\n */\n async solverSolve(\n token: string,\n options: SolveOptions,\n ): Promise<BaseResponse<SolveData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_SOLVE, {\n original: options.original,\n user: options.user,\n autopencilmarks: options.autoPencilmarks,\n pencilmarks: options.pencilmarks,\n filters: options.filters,\n techniques: options.techniques,\n });\n\n const fullUrl = `${this.baseUrl}${url}`;\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n };\n\n if (token) {\n requestHeaders[\"Authorization\"] = `Bearer ${token}`;\n }\n\n // Use 120 second timeout for solve (advanced techniques can be slow)\n const response = await this.networkClient.request<\n BaseResponse<SolveData> | HintAccessDeniedResponse\n >(fullUrl, {\n method: \"GET\",\n headers: requestHeaders,\n timeout: 120000,\n });\n\n // Check for hint access denied (402)\n if (response.status === 402 && response.data) {\n const errorResponse = response.data as HintAccessDeniedResponse;\n if (errorResponse.error?.code === \"HINT_ACCESS_DENIED\") {\n throw new HintAccessDeniedError(errorResponse.error);\n }\n }\n\n // Check for other errors\n if (!response.ok || response.data === undefined) {\n throw new Error(\"Failed to get hints from solver\");\n }\n\n return (await decryptSolutionFields(\n response.data,\n )) as BaseResponse<SolveData>;\n }\n\n /**\n * Validate that a Sudoku puzzle has a unique solution.\n * Uses a longer timeout (120s) because validation involves iterative solving.\n */\n async solverValidate(\n token: string,\n options: ValidateOptions,\n ): Promise<BaseResponse<ValidateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_VALIDATE, {\n original: options.original,\n });\n\n // Use 120 second timeout for validation (iterative solving can be slow)\n return this.request<BaseResponse<ValidateData>>(url, {\n token,\n timeout: 120000,\n });\n }\n\n /**\n * Generate a new random Sudoku puzzle\n */\n async solverGenerate(\n token: string,\n options: GenerateOptions = {},\n ): Promise<BaseResponse<GenerateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_GENERATE, {\n symmetrical: options.symmetrical,\n });\n\n return this.request<BaseResponse<GenerateData>>(url, { token });\n }\n\n // ===========================================================================\n // Play (Game Session) Endpoints\n // ===========================================================================\n\n /**\n * Start a new game session\n */\n async playStart(\n token: string,\n data: GameStartRequest,\n ): Promise<BaseResponse<GameStartResponse>> {\n return this.request<BaseResponse<GameStartResponse>>(\n this.config.ENDPOINTS.PLAY_START,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Finish the current game session and get rewards\n */\n async playFinish(\n token: string,\n data: GameFinishRequest,\n ): Promise<BaseResponse<GameFinishResponse>> {\n return this.request<BaseResponse<GameFinishResponse>>(\n this.config.ENDPOINTS.PLAY_FINISH,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Gamification Endpoints\n // ===========================================================================\n\n /**\n * Get user's gamification stats (points, level, badges)\n */\n async getGamificationStats(\n token: string,\n ): Promise<BaseResponse<GamificationStats>> {\n return this.request<BaseResponse<GamificationStats>>(\n this.config.ENDPOINTS.GAMIFICATION_STATS,\n { token },\n );\n }\n\n /**\n * Get all badge definitions (public)\n */\n async getBadgeDefinitions(): Promise<BaseResponse<BadgeDefinition[]>> {\n return this.request<BaseResponse<BadgeDefinition[]>>(\n this.config.ENDPOINTS.GAMIFICATION_BADGES,\n );\n }\n\n /**\n * Get user's point transaction history\n */\n async getPointHistory(\n token: string,\n options?: { limit?: number; offset?: number },\n ): Promise<BaseResponse<PointTransaction[]>> {\n let endpoint = this.config.ENDPOINTS.GAMIFICATION_HISTORY;\n if (options?.limit || options?.offset) {\n const params = createURLSearchParams();\n if (options.limit) params.append(\"limit\", String(options.limit));\n if (options.offset) params.append(\"offset\", String(options.offset));\n endpoint = `${endpoint}?${params.toString()}`;\n }\n return this.request<BaseResponse<PointTransaction[]>>(endpoint, { token });\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Factory function to create a new SudojoClient instance.\n *\n * Equivalent to `new SudojoClient(networkClient, baseUrl)` but useful\n * for dependency injection and functional composition patterns.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL for the Sudojo API\n * @returns A new SudojoClient instance\n */\nexport const createSudojoClient = (\n networkClient: NetworkClient,\n baseUrl: string,\n): SudojoClient => {\n return new SudojoClient(networkClient, baseUrl);\n};\n\n// =============================================================================\n// Utility Exports\n// =============================================================================\n\n/**\n * Re-exported UUID validation utilities from `@sudobility/sudojo_types`.\n *\n * These are used internally by the SudojoClient for parameter validation\n * and are also exported for consumer convenience. Use `isValidUUID` for\n * boolean checks and `validateUUID` when you want an error thrown on invalid input.\n *\n * - `isValidUUID(value)` - Returns true if the string is a valid UUID v4\n * - `validateUUID(value, label)` - Returns the UUID or throws an Error with the label\n */\nexport { isValidUUID, validateUUID };\n"]}
1
+ {"version":3,"file":"sudojo-client.js","sourceRoot":"","sources":["../../src/network/sudojo-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NetworkClient, UserInfoResponse } from \"@sudobility/types\";\nimport {\n type BadgeDefinition,\n type BaseResponse,\n type Board,\n type BoardCountsByTechniqueData,\n type BoardCountsData,\n type BoardCreateRequest,\n type BoardQueryParams,\n type BoardUpdateRequest,\n type Challenge,\n type ChallengeCreateRequest,\n type ChallengeQueryParams,\n type ChallengeUpdateRequest,\n type Daily,\n type DailyCreateRequest,\n type DailyUpdateRequest,\n type ExampleCountsData,\n type GameFinishRequest,\n type GameFinishResponse,\n type GameStartRequest,\n type GameStartResponse,\n type GamificationStats,\n type GenerateData,\n type GenerateOptions,\n type HealthCheckData,\n type HintAccessDeniedResponse,\n isValidUUID,\n type Learning,\n type LearningCreateRequest,\n type LearningQueryParams,\n type LearningUpdateRequest,\n type Level,\n type LevelCreateRequest,\n type LevelUpdateRequest,\n type Optional,\n type PointTransaction,\n type PracticesBulkDeleteData,\n type PracticesRegenerateHintsData,\n type SolveData,\n type SolveOptions,\n type SubscriptionResult,\n type Technique,\n type TechniqueCreateRequest,\n type TechniqueExample,\n type TechniqueExampleCreateRequest,\n type TechniqueExampleQueryParams,\n type TechniquePractice,\n type TechniquePracticeCountItem,\n type TechniquePracticeCreateRequest,\n type TechniqueQueryParams,\n type TechniqueUpdateRequest,\n type UpdateStatsData,\n type ValidateData,\n type ValidateOptions,\n validateUUID,\n} from \"@sudobility/sudojo_types\";\nimport { HintAccessDeniedError } from \"../errors\";\n\n// Re-export option types for convenience\nexport type { SolveOptions, ValidateOptions, GenerateOptions };\n\n// =============================================================================\n// Solution Decryption\n// =============================================================================\n\nlet _solutionKey: CryptoKey | null = null;\n\n/**\n * Configure the symmetric key used to decrypt `solution` fields in API responses.\n * Call once at app startup with the hex-encoded 256-bit key.\n * If not called (or called with empty string), encrypted solutions pass through as-is.\n */\nexport async function configureSolutionKey(keyHex: string): Promise<void> {\n if (!keyHex) return;\n const hexPairs = keyHex.match(/.{2}/g);\n if (!hexPairs) return;\n const keyBytes = new Uint8Array(hexPairs.map((byte) => parseInt(byte, 16)));\n _solutionKey = await globalThis.crypto.subtle.importKey(\n \"raw\",\n keyBytes,\n \"AES-GCM\",\n false,\n [\"decrypt\"],\n );\n}\n\nasync function decryptSolution(encrypted: string): Promise<string> {\n if (!_solutionKey) return encrypted;\n\n const raw = globalThis.atob(encrypted.slice(4)); // strip \"enc:\" prefix\n const bytes = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n bytes[i] = raw.charCodeAt(i);\n }\n\n const nonce = bytes.slice(0, 12);\n const ciphertextWithTag = bytes.slice(12);\n\n const decrypted = await globalThis.crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: nonce },\n _solutionKey,\n ciphertextWithTag,\n );\n\n return new TextDecoder().decode(decrypted);\n}\n\nasync function decryptSolutionFields(data: unknown): Promise<unknown> {\n if (data === null || data === undefined) return data;\n\n if (Array.isArray(data)) {\n return Promise.all(data.map((item) => decryptSolutionFields(item)));\n }\n\n if (typeof data === \"object\") {\n const obj = data as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n if (\n key === \"solution\" &&\n typeof obj[key] === \"string\" &&\n (obj[key] as string).startsWith(\"enc:\")\n ) {\n result[key] = await decryptSolution(obj[key] as string);\n } else {\n result[key] = await decryptSolutionFields(obj[key]);\n }\n }\n return result;\n }\n\n return data;\n}\n\n// =============================================================================\n// URL Search Params Utility\n// =============================================================================\n\n/**\n * Creates a lightweight URL search params builder.\n *\n * This is a custom implementation instead of the standard `URLSearchParams`\n * because the solver API requires a special encoding behavior: **commas must\n * NOT be percent-encoded** in pencilmark values. The standard `URLSearchParams`\n * encodes commas as `%2C`, which the Kotlin-based solver backend does not decode.\n *\n * @returns An object with `append(key, value)` and `toString()` methods\n *\n * @example\n * ```ts\n * const params = createURLSearchParams();\n * params.append(\"pencilmarks\", \"1,2,3\");\n * params.toString(); // \"pencilmarks=1,2,3\" (commas preserved)\n * ```\n */\nconst createURLSearchParams = () => {\n const params: Record<string, string[]> = {};\n return {\n append: (key: string, value: string) => {\n if (!params[key]) {\n params[key] = [];\n }\n params[key]?.push(value);\n },\n toString: () => {\n return Object.entries(params)\n .flatMap(([key, values]) =>\n values.map(\n (value) =>\n // Don't encode commas - the solver API expects literal commas in pencilmarks\n `${encodeURIComponent(key)}=${encodeURIComponent(value).replace(/%2C/g, \",\")}`,\n ),\n )\n .join(\"&\");\n },\n };\n};\n\n// =============================================================================\n// API Configuration Factory\n// =============================================================================\n\nconst createApiConfig = (baseUrl: string) => ({\n BASE_URL: baseUrl,\n ENDPOINTS: {\n // Health\n HEALTH: \"/\",\n\n // Levels\n LEVELS: \"/api/v1/levels\",\n LEVEL: (level: number) => `/api/v1/levels/${level}`,\n\n // Techniques\n TECHNIQUES: \"/api/v1/techniques\",\n TECHNIQUE: (technique: number) => `/api/v1/techniques/${technique}`,\n\n // Learning\n LEARNING: \"/api/v1/learning\",\n LEARNING_ITEM: (uuid: string) => `/api/v1/learning/${uuid}`,\n\n // Boards\n BOARDS: \"/api/v1/boards\",\n BOARDS_RANDOM: \"/api/v1/boards/random\",\n BOARD: (uuid: string) => `/api/v1/boards/${uuid}`,\n\n // Dailies\n DAILIES: \"/api/v1/dailies\",\n DAILIES_TODAY: \"/api/v1/dailies/today\",\n DAILIES_DATE: (date: string) => `/api/v1/dailies/date/${date}`,\n DAILY: (uuid: string) => `/api/v1/dailies/${uuid}`,\n\n // Challenges\n CHALLENGES: \"/api/v1/challenges\",\n CHALLENGES_RANDOM: \"/api/v1/challenges/random\",\n CHALLENGE: (uuid: string) => `/api/v1/challenges/${uuid}`,\n\n // Users\n USER: (userId: string) => `/api/v1/users/${userId}`,\n USER_SUBSCRIPTIONS: (userId: string) =>\n `/api/v1/users/${userId}/subscriptions`,\n\n // Solver\n SOLVER_SOLVE: \"/api/v1/solver/solve\",\n SOLVER_VALIDATE: \"/api/v1/solver/validate\",\n SOLVER_GENERATE: \"/api/v1/solver/generate\",\n\n // Practices\n PRACTICES: \"/api/v1/practices\",\n PRACTICES_COUNTS: \"/api/v1/practices/counts\",\n PRACTICE_RANDOM: (technique: number) =>\n `/api/v1/practices/technique/${technique}/random`,\n\n // Examples\n EXAMPLES: \"/api/v1/examples\",\n EXAMPLES_COUNTS: \"/api/v1/examples/counts\",\n\n // Boards counts\n BOARDS_COUNTS: \"/api/v1/boards/counts\",\n BOARDS_COUNTS_BY_TECHNIQUE: \"/api/v1/boards/counts/by-technique\",\n BOARDS_UPDATE_STATS: \"/api/v1/boards/update-stats\",\n\n // Play (game sessions)\n PLAY_START: \"/api/v1/play/start\",\n PLAY_FINISH: \"/api/v1/play/finish\",\n\n // Gamification\n GAMIFICATION_STATS: \"/api/v1/gamification/stats\",\n GAMIFICATION_BADGES: \"/api/v1/gamification/badges\",\n GAMIFICATION_HISTORY: \"/api/v1/gamification/history\",\n },\n DEFAULT_HEADERS: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n});\n\n// =============================================================================\n// Sudojo Client Class\n// =============================================================================\n\n/**\n * Type-safe client for the Sudojo REST API.\n *\n * Provides methods for all Sudojo API endpoints including levels, techniques,\n * boards, dailies, challenges, users, solver, practices, examples, and gamification.\n *\n * ## Error Handling\n *\n * All methods throw errors on failure:\n * - **Network errors**: Thrown by the underlying `NetworkClient` (e.g., connection refused, timeout)\n * - **Empty response**: Throws `Error(\"No data received from server\")` when the server returns no data\n * - **Validation errors**: Thrown before the request for invalid parameters (e.g., invalid UUID, level out of range)\n * - **HTTP 402**: `solverSolve()` throws {@link HintAccessDeniedError} when the hint level exceeds the user's tier\n * - **Other HTTP errors**: Depend on the `NetworkClient` implementation - typically thrown as generic `Error`\n *\n * ## Authentication\n *\n * Most methods accept a `token` parameter (Firebase ID token). The token is sent\n * as a `Bearer` token in the `Authorization` header. Public endpoints (health,\n * levels, boards, etc.) accept but do not require a token. User-specific endpoints\n * (subscriptions, gamification) require a valid token.\n *\n * ## Usage\n *\n * ```typescript\n * const client = new SudojoClient(networkClient, \"https://api.sudojo.com\");\n * const levels = await client.getLevels(token);\n * const daily = await client.getDailyByDate(token, \"2024-01-15\");\n * ```\n */\nexport class SudojoClient {\n private baseUrl: string;\n private headers: Record<string, string>;\n private networkClient: NetworkClient;\n private config: ReturnType<typeof createApiConfig>;\n\n /**\n * Create a SudojoClient instance.\n *\n * @param networkClient - Network client for making HTTP requests (from `@sudobility/types`)\n * @param baseUrl - Base URL for the Sudojo API (e.g., \"https://api.sudojo.com\")\n */\n constructor(networkClient: NetworkClient, baseUrl: string) {\n this.config = createApiConfig(baseUrl);\n this.baseUrl = this.config.BASE_URL;\n this.networkClient = networkClient;\n\n this.headers = {\n ...this.config.DEFAULT_HEADERS,\n };\n }\n\n // ===========================================================================\n // Private Request Method\n // ===========================================================================\n\n private async request<T>(\n endpoint: string,\n options: {\n method?: Optional<\"GET\" | \"POST\" | \"PUT\" | \"DELETE\">;\n body?: Optional<Record<string, unknown>>;\n headers?: Optional<Record<string, string>>;\n token?: Optional<string>;\n timeout?: Optional<number>;\n } = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n ...options.headers,\n };\n\n // Add authorization header if token is provided\n if (options.token) {\n requestHeaders[\"Authorization\"] = `Bearer ${options.token}`;\n }\n\n const requestOptions: {\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n headers: Record<string, string>;\n body?: string;\n timeout?: number;\n } = {\n method: options.method || \"GET\",\n headers: requestHeaders,\n };\n\n // Add body for POST/PUT/DELETE requests\n if (options.body && options.method !== \"GET\") {\n requestOptions.body = JSON.stringify(options.body);\n }\n\n // Add timeout if specified\n if (options.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await this.networkClient.request<T>(url, requestOptions);\n\n if (response.data === undefined) {\n throw new Error(\"No data received from server\");\n }\n\n return (await decryptSolutionFields(response.data)) as T;\n }\n\n // ===========================================================================\n // Health Check\n // ===========================================================================\n\n async getHealth(): Promise<BaseResponse<HealthCheckData>> {\n return this.request<BaseResponse<HealthCheckData>>(\n this.config.ENDPOINTS.HEALTH,\n );\n }\n\n // ===========================================================================\n // Levels\n // ===========================================================================\n\n async getLevels(token: string): Promise<BaseResponse<Level[]>> {\n return this.request<BaseResponse<Level[]>>(this.config.ENDPOINTS.LEVELS, {\n token,\n });\n }\n\n async getLevel(token: string, level: number): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n { token },\n );\n }\n\n async createLevel(\n token: string,\n data: LevelCreateRequest,\n ): Promise<BaseResponse<Level>> {\n return this.request<BaseResponse<Level>>(this.config.ENDPOINTS.LEVELS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateLevel(\n token: string,\n level: number,\n data: LevelUpdateRequest,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLevel(\n token: string,\n level: number,\n ): Promise<BaseResponse<Level>> {\n if (level < 1 || level > 12) {\n throw new Error(`Invalid level: ${level}. Expected 1-12`);\n }\n return this.request<BaseResponse<Level>>(\n this.config.ENDPOINTS.LEVEL(level),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Techniques\n // ===========================================================================\n\n async getTechniques(\n token: string,\n queryParams?: TechniqueQueryParams,\n ): Promise<BaseResponse<Technique[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.TECHNIQUES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Technique[]>>(endpoint, { token });\n }\n\n async getTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n { token },\n );\n }\n\n async createTechnique(\n token: string,\n data: TechniqueCreateRequest,\n ): Promise<BaseResponse<Technique>> {\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateTechnique(\n token: string,\n technique: number,\n data: TechniqueUpdateRequest,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteTechnique(\n token: string,\n technique: number,\n ): Promise<BaseResponse<Technique>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<Technique>>(\n this.config.ENDPOINTS.TECHNIQUE(technique),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Learning\n // ===========================================================================\n\n async getLearning(\n token: string,\n queryParams?: LearningQueryParams,\n ): Promise<BaseResponse<Learning[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n if (queryParams?.language_code) {\n params.append(\"language_code\", queryParams.language_code);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.LEARNING}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Learning[]>>(endpoint, { token });\n }\n\n async getLearningItem(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n { token },\n );\n }\n\n async createLearning(\n token: string,\n data: LearningCreateRequest,\n ): Promise<BaseResponse<Learning>> {\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateLearning(\n token: string,\n uuid: string,\n data: LearningUpdateRequest,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteLearning(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Learning>> {\n const validatedUuid = validateUUID(uuid, \"Learning UUID\");\n return this.request<BaseResponse<Learning>>(\n this.config.ENDPOINTS.LEARNING_ITEM(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Boards\n // ===========================================================================\n\n async getBoards(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.limit !== undefined) {\n params.append(\"limit\", String(queryParams.limit));\n }\n if (queryParams?.offset !== undefined) {\n params.append(\"offset\", String(queryParams.offset));\n }\n if (queryParams?.techniques !== undefined) {\n params.append(\"techniques\", String(queryParams.techniques));\n }\n if (queryParams?.technique_bit !== undefined) {\n params.append(\"technique_bit\", String(queryParams.technique_bit));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board[]>>(endpoint, { token });\n }\n\n async getRandomBoard(\n token: string,\n queryParams?: BoardQueryParams,\n ): Promise<BaseResponse<Board>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n\n if (queryParams?.symmetrical !== undefined) {\n params.append(\"symmetrical\", String(queryParams.symmetrical));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.BOARDS_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Board>>(endpoint, { token });\n }\n\n async getBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n { token },\n );\n }\n\n async createBoard(\n token: string,\n data: BoardCreateRequest,\n ): Promise<BaseResponse<Board>> {\n return this.request<BaseResponse<Board>>(this.config.ENDPOINTS.BOARDS, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateBoard(\n token: string,\n uuid: string,\n data: BoardUpdateRequest,\n ): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteBoard(token: string, uuid: string): Promise<BaseResponse<Board>> {\n const validatedUuid = validateUUID(uuid, \"Board UUID\");\n return this.request<BaseResponse<Board>>(\n this.config.ENDPOINTS.BOARD(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Dailies\n // ===========================================================================\n\n async getDailies(token: string): Promise<BaseResponse<Daily[]>> {\n return this.request<BaseResponse<Daily[]>>(this.config.ENDPOINTS.DAILIES, {\n token,\n });\n }\n\n async getTodayDaily(token: string): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_TODAY,\n { token },\n );\n }\n\n async getDailyByDate(\n token: string,\n date: string,\n ): Promise<BaseResponse<Daily>> {\n // Validate date format (YYYY-MM-DD)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) {\n throw new Error(\n `Invalid date format: \"${date}\". Expected YYYY-MM-DD format`,\n );\n }\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILIES_DATE(date),\n { token },\n );\n }\n\n async getDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n { token },\n );\n }\n\n async createDaily(\n token: string,\n data: DailyCreateRequest,\n ): Promise<BaseResponse<Daily>> {\n return this.request<BaseResponse<Daily>>(this.config.ENDPOINTS.DAILIES, {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n });\n }\n\n async updateDaily(\n token: string,\n uuid: string,\n data: DailyUpdateRequest,\n ): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteDaily(token: string, uuid: string): Promise<BaseResponse<Daily>> {\n const validatedUuid = validateUUID(uuid, \"Daily UUID\");\n return this.request<BaseResponse<Daily>>(\n this.config.ENDPOINTS.DAILY(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Challenges\n // ===========================================================================\n\n async getChallenges(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge[]>>(endpoint, { token });\n }\n\n async getRandomChallenge(\n token: string,\n queryParams?: ChallengeQueryParams,\n ): Promise<BaseResponse<Challenge>> {\n const params = createURLSearchParams();\n\n if (queryParams?.level !== undefined) {\n params.append(\"level\", String(queryParams.level));\n }\n if (queryParams?.difficulty) {\n params.append(\"difficulty\", queryParams.difficulty);\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.CHALLENGES_RANDOM}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<Challenge>>(endpoint, { token });\n }\n\n async getChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n { token },\n );\n }\n\n async createChallenge(\n token: string,\n data: ChallengeCreateRequest,\n ): Promise<BaseResponse<Challenge>> {\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async updateChallenge(\n token: string,\n uuid: string,\n data: ChallengeUpdateRequest,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"PUT\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n async deleteChallenge(\n token: string,\n uuid: string,\n ): Promise<BaseResponse<Challenge>> {\n const validatedUuid = validateUUID(uuid, \"Challenge UUID\");\n return this.request<BaseResponse<Challenge>>(\n this.config.ENDPOINTS.CHALLENGE(validatedUuid),\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Users\n // ===========================================================================\n\n async getUser(\n token: string,\n userId: string,\n ): Promise<BaseResponse<UserInfoResponse>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n return this.request<BaseResponse<UserInfoResponse>>(\n this.config.ENDPOINTS.USER(userId),\n {\n token,\n },\n );\n }\n\n async getUserSubscription(\n token: string,\n userId: string,\n testMode?: boolean,\n ): Promise<BaseResponse<SubscriptionResult>> {\n if (!userId || userId.length === 0 || userId.length > 128) {\n throw new Error(`Invalid userId: \"${userId}\". Expected 1-128 characters`);\n }\n const endpoint = testMode\n ? `${this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId)}?testMode=true`\n : this.config.ENDPOINTS.USER_SUBSCRIPTIONS(userId);\n return this.request<BaseResponse<SubscriptionResult>>(endpoint, {\n token,\n });\n }\n\n // ===========================================================================\n // Practices\n // ===========================================================================\n\n /**\n * Get practice counts for all techniques\n */\n async getPracticeCounts(\n token: string,\n ): Promise<BaseResponse<TechniquePracticeCountItem[]>> {\n return this.request<BaseResponse<TechniquePracticeCountItem[]>>(\n this.config.ENDPOINTS.PRACTICES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get a random practice for a specific technique\n */\n async getRandomPractice(\n token: string,\n technique: number,\n ): Promise<BaseResponse<TechniquePractice>> {\n if (technique < 1) {\n throw new Error(`Invalid technique: ${technique}. Expected >= 1`);\n }\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICE_RANDOM(technique),\n { token },\n );\n }\n\n /**\n * Create a new practice (admin only)\n */\n async createPractice(\n token: string,\n data: TechniquePracticeCreateRequest,\n ): Promise<BaseResponse<TechniquePractice>> {\n return this.request<BaseResponse<TechniquePractice>>(\n this.config.ENDPOINTS.PRACTICES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Delete all practices (admin only, requires confirm=true)\n */\n async deleteAllPractices(\n token: string,\n ): Promise<BaseResponse<PracticesBulkDeleteData>> {\n return this.request<BaseResponse<PracticesBulkDeleteData>>(\n `${this.config.ENDPOINTS.PRACTICES}?confirm=true`,\n {\n method: \"DELETE\",\n token,\n },\n );\n }\n\n /**\n * Regenerate hint_data for all practices by calling the solver (admin only).\n */\n async regeneratePracticeHints(\n token: string,\n ): Promise<BaseResponse<PracticesRegenerateHintsData>> {\n return this.request<BaseResponse<PracticesRegenerateHintsData>>(\n `${this.config.ENDPOINTS.PRACTICES}/regenerate-hints`,\n {\n method: \"POST\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Examples\n // ===========================================================================\n\n /**\n * Get example counts for all techniques\n */\n async getExampleCounts(\n token: string,\n ): Promise<BaseResponse<ExampleCountsData>> {\n return this.request<BaseResponse<ExampleCountsData>>(\n this.config.ENDPOINTS.EXAMPLES_COUNTS,\n { token },\n );\n }\n\n /**\n * Get examples, optionally filtered by technique\n */\n async getExamples(\n token: string,\n queryParams?: TechniqueExampleQueryParams,\n ): Promise<BaseResponse<TechniqueExample[]>> {\n const params = createURLSearchParams();\n\n if (queryParams?.technique !== undefined) {\n params.append(\"technique\", String(queryParams.technique));\n }\n\n const query = params.toString();\n const endpoint = `${this.config.ENDPOINTS.EXAMPLES}${query ? `?${query}` : \"\"}`;\n\n return this.request<BaseResponse<TechniqueExample[]>>(endpoint, { token });\n }\n\n /**\n * Create a new example (admin only)\n */\n async createExample(\n token: string,\n data: TechniqueExampleCreateRequest,\n ): Promise<BaseResponse<TechniqueExample>> {\n return this.request<BaseResponse<TechniqueExample>>(\n this.config.ENDPOINTS.EXAMPLES,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Board Counts\n // ===========================================================================\n\n /**\n * Get board counts (total and without techniques)\n */\n async getBoardCounts(token: string): Promise<BaseResponse<BoardCountsData>> {\n return this.request<BaseResponse<BoardCountsData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS,\n { token },\n );\n }\n\n /**\n * Get board counts by technique (count of boards with each technique bit set)\n * Returns Record<number, number> where key is technique ID and value is count\n */\n async getBoardCountsByTechnique(\n token: string,\n ): Promise<BaseResponse<BoardCountsByTechniqueData>> {\n return this.request<BaseResponse<BoardCountsByTechniqueData>>(\n this.config.ENDPOINTS.BOARDS_COUNTS_BY_TECHNIQUE,\n { token },\n );\n }\n\n /**\n * Calculate and update puzzle stats (percentages) on levels and techniques.\n * Requires admin authentication.\n */\n async updatePuzzleStats(\n token: string,\n ): Promise<BaseResponse<UpdateStatsData>> {\n return this.request<BaseResponse<UpdateStatsData>>(\n this.config.ENDPOINTS.BOARDS_UPDATE_STATS,\n {\n method: \"POST\",\n token,\n },\n );\n }\n\n // ===========================================================================\n // Solver\n // ===========================================================================\n\n /**\n * Builds an endpoint path with query parameters for solver endpoints\n */\n private buildSolverUrl(\n endpoint: string,\n params: Record<string, string | boolean | undefined>,\n ): string {\n const searchParams = createURLSearchParams();\n // Sort keys alphabetically to match Kotlin behavior\n const sortedKeys = Object.keys(params).sort();\n for (const key of sortedKeys) {\n const value = params[key];\n if (value !== undefined) {\n searchParams.append(key, String(value));\n }\n }\n const query = searchParams.toString();\n // Return endpoint + query only, baseUrl is added by request()\n return `${endpoint}${query ? `?${query}` : \"\"}`;\n }\n\n /**\n * Get hints for solving a Sudoku puzzle\n * @throws {HintAccessDeniedError} When hint level exceeds user's subscription tier\n */\n async solverSolve(\n token: string,\n options: SolveOptions,\n ): Promise<BaseResponse<SolveData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_SOLVE, {\n original: options.original,\n user: options.user,\n autopencilmarks: options.autoPencilmarks,\n pencilmarks: options.pencilmarks,\n filters: options.filters,\n techniques: options.techniques,\n });\n\n const fullUrl = `${this.baseUrl}${url}`;\n const requestHeaders: Record<string, string> = {\n ...this.headers,\n };\n\n if (token) {\n requestHeaders[\"Authorization\"] = `Bearer ${token}`;\n }\n\n // Use 120 second timeout for solve (advanced techniques can be slow)\n const response = await this.networkClient.request<\n BaseResponse<SolveData> | HintAccessDeniedResponse\n >(fullUrl, {\n method: \"GET\",\n headers: requestHeaders,\n timeout: 120000,\n });\n\n // Check for hint access denied (402)\n if (response.status === 402 && response.data) {\n const errorResponse = response.data as HintAccessDeniedResponse;\n if (errorResponse.error?.code === \"HINT_ACCESS_DENIED\") {\n throw new HintAccessDeniedError(errorResponse.error);\n }\n }\n\n // Check for other errors\n if (!response.ok || response.data === undefined) {\n throw new Error(\"Failed to get hints from solver\");\n }\n\n return (await decryptSolutionFields(\n response.data,\n )) as BaseResponse<SolveData>;\n }\n\n /**\n * Validate that a Sudoku puzzle has a unique solution.\n * Uses a longer timeout (120s) because validation involves iterative solving.\n */\n async solverValidate(\n token: string,\n options: ValidateOptions,\n ): Promise<BaseResponse<ValidateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_VALIDATE, {\n original: options.original,\n });\n\n // Use 120 second timeout for validation (iterative solving can be slow)\n return this.request<BaseResponse<ValidateData>>(url, {\n token,\n timeout: 120000,\n });\n }\n\n /**\n * Generate a new random Sudoku puzzle\n */\n async solverGenerate(\n token: string,\n options: GenerateOptions = {},\n ): Promise<BaseResponse<GenerateData>> {\n const url = this.buildSolverUrl(this.config.ENDPOINTS.SOLVER_GENERATE, {\n symmetrical: options.symmetrical,\n });\n\n return this.request<BaseResponse<GenerateData>>(url, { token });\n }\n\n // ===========================================================================\n // Play (Game Session) Endpoints\n // ===========================================================================\n\n /**\n * Start a new game session\n */\n async playStart(\n token: string,\n data: GameStartRequest,\n ): Promise<BaseResponse<GameStartResponse>> {\n return this.request<BaseResponse<GameStartResponse>>(\n this.config.ENDPOINTS.PLAY_START,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n /**\n * Finish the current game session and get rewards\n */\n async playFinish(\n token: string,\n data: GameFinishRequest,\n ): Promise<BaseResponse<GameFinishResponse>> {\n return this.request<BaseResponse<GameFinishResponse>>(\n this.config.ENDPOINTS.PLAY_FINISH,\n {\n method: \"POST\",\n body: data as unknown as Record<string, unknown>,\n token,\n },\n );\n }\n\n // ===========================================================================\n // Gamification Endpoints\n // ===========================================================================\n\n /**\n * Get user's gamification stats (points, level, badges)\n */\n async getGamificationStats(\n token: string,\n ): Promise<BaseResponse<GamificationStats>> {\n return this.request<BaseResponse<GamificationStats>>(\n this.config.ENDPOINTS.GAMIFICATION_STATS,\n { token },\n );\n }\n\n /**\n * Get all badge definitions (public)\n */\n async getBadgeDefinitions(): Promise<BaseResponse<BadgeDefinition[]>> {\n return this.request<BaseResponse<BadgeDefinition[]>>(\n this.config.ENDPOINTS.GAMIFICATION_BADGES,\n );\n }\n\n /**\n * Get user's point transaction history\n */\n async getPointHistory(\n token: string,\n options?: { limit?: number; offset?: number },\n ): Promise<BaseResponse<PointTransaction[]>> {\n let endpoint = this.config.ENDPOINTS.GAMIFICATION_HISTORY;\n if (options?.limit || options?.offset) {\n const params = createURLSearchParams();\n if (options.limit) params.append(\"limit\", String(options.limit));\n if (options.offset) params.append(\"offset\", String(options.offset));\n endpoint = `${endpoint}?${params.toString()}`;\n }\n return this.request<BaseResponse<PointTransaction[]>>(endpoint, { token });\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Factory function to create a new SudojoClient instance.\n *\n * Equivalent to `new SudojoClient(networkClient, baseUrl)` but useful\n * for dependency injection and functional composition patterns.\n *\n * @param networkClient - Network client for making HTTP requests\n * @param baseUrl - Base URL for the Sudojo API\n * @returns A new SudojoClient instance\n */\nexport const createSudojoClient = (\n networkClient: NetworkClient,\n baseUrl: string,\n): SudojoClient => {\n return new SudojoClient(networkClient, baseUrl);\n};\n\n// =============================================================================\n// Utility Exports\n// =============================================================================\n\n/**\n * Re-exported UUID validation utilities from `@sudobility/sudojo_types`.\n *\n * These are used internally by the SudojoClient for parameter validation\n * and are also exported for consumer convenience. Use `isValidUUID` for\n * boolean checks and `validateUUID` when you want an error thrown on invalid input.\n *\n * - `isValidUUID(value)` - Returns true if the string is a valid UUID v4\n * - `validateUUID(value, label)` - Returns the UUID or throws an Error with the label\n */\nexport { isValidUUID, validateUUID };\n"]}
@@ -6,12 +6,14 @@ export declare const solverQueryKeys: {
6
6
  autoPencilmarks?: boolean | undefined;
7
7
  pencilmarks?: string | undefined;
8
8
  filters?: string | undefined;
9
+ techniques?: string | undefined;
9
10
  }) => readonly ["sudojo", "solver", "solve", {
10
11
  original: string;
11
12
  user: string;
12
13
  autoPencilmarks?: boolean | undefined;
13
14
  pencilmarks?: string | undefined;
14
15
  filters?: string | undefined;
16
+ techniques?: string | undefined;
15
17
  }];
16
18
  readonly validate: (original: string) => readonly ["sudojo", "solver", "validate", string];
17
19
  readonly generate: (options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../../../src/solver/hooks/query-keys.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,eAAe;wBAHL,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;8BAWjC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACtC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAC9B;kBALW,MAAM;cACV,MAAM;0BACM,OAAO,GAAG,SAAS;sBACvB,MAAM,GAAG,SAAS;kBACtB,MAAM,GAAG,SAAS;;kCAOT,MAAM;kCAON;QAAE,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE;sBAArB,OAAO,GAAG,SAAS;;CAEhD,CAAC;AAaX,eAAO,MAAM,oBAAoB,QAAO,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAEnE,CAAC"}
1
+ {"version":3,"file":"query-keys.d.ts","sourceRoot":"","sources":["../../../src/solver/hooks/query-keys.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,eAAe;wBAHL,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;8BAWjC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACtC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACjC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACjC;kBANW,MAAM;cACV,MAAM;0BACM,OAAO,GAAG,SAAS;sBACvB,MAAM,GAAG,SAAS;kBACtB,MAAM,GAAG,SAAS;qBACf,MAAM,GAAG,SAAS;;kCAOZ,MAAM;kCAON;QAAE,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE;sBAArB,OAAO,GAAG,SAAS;;CAEhD,CAAC;AAaX,eAAO,MAAM,oBAAoB,QAAO,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAEnE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"query-keys.js","sourceRoot":"","sources":["../../../src/solver/hooks/query-keys.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,GAAG,GAAkC,EAAE,CACrD,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAEhC,MAAM,CAAC,MAAM,eAAe,GAAG;IAE7B,GAAG,EAAE,UAAU;IAMf,KAAK,EAAE,CAAC,OAMP,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,CAAU;IAMlD,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAC7B,CAAC,GAAG,UAAU,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAU;IAMlD,QAAQ,EAAE,CAAC,OAA+C,EAAE,EAAE,CAC5D,CAAC,GAAG,UAAU,EAAE,EAAE,UAAU,EAAE,OAAO,CAAU;CACzC,CAAC;AAaX,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAkC,EAAE;IACtE,OAAO,eAAe,CAAC,GAAG,EAAE,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["/**\n * Query Key Factory for Sudojo Solver TanStack Query\n *\n * Provides type-safe, consistent query keys for Solver API endpoints.\n * Following TanStack Query best practices for key structure.\n *\n * ## Key Hierarchy\n *\n * All solver keys start with `[\"sudojo\", \"solver\"]` as the root:\n * - `[\"sudojo\", \"solver\", \"solve\", { original, user, ... }]` - solve hints\n * - `[\"sudojo\", \"solver\", \"validate\", originalPuzzle]` - validation\n * - `[\"sudojo\", \"solver\", \"generate\", { symmetrical }]` - generation\n *\n * ## Invalidation\n *\n * Use `getSolverServiceKeys()` to invalidate all solver queries at once.\n * Individual solve/validate/generate keys include their parameters so\n * different inputs produce distinct cache entries.\n */\n\nconst solverBase = (): readonly [\"sudojo\", \"solver\"] =>\n [\"sudojo\", \"solver\"] as const;\n\nexport const solverQueryKeys = {\n /** Root key for all solver queries. Use for bulk invalidation. */\n all: solverBase,\n\n /**\n * Key for a solve hints query. Includes all puzzle state parameters\n * so different board states produce separate cache entries.\n */\n solve: (options: {\n original: string;\n user: string;\n autoPencilmarks?: boolean | undefined;\n pencilmarks?: string | undefined;\n filters?: string | undefined;\n }) => [...solverBase(), \"solve\", options] as const,\n\n /**\n * Key for a puzzle validation query. Since validation is deterministic\n * for a given original puzzle string, only the puzzle string is needed.\n */\n validate: (original: string) =>\n [...solverBase(), \"validate\", original] as const,\n\n /**\n * Key for a puzzle generation query. Includes symmetry preference\n * as different options may produce different puzzle types.\n */\n generate: (options?: { symmetrical?: boolean | undefined }) =>\n [...solverBase(), \"generate\", options] as const,\n} as const;\n\n/**\n * Helper to get the root key for all solver service queries.\n * Useful for bulk invalidation of the entire solver cache.\n *\n * @returns The root query key `[\"sudojo\", \"solver\"]`\n *\n * @example\n * ```ts\n * queryClient.invalidateQueries({ queryKey: getSolverServiceKeys() });\n * ```\n */\nexport const getSolverServiceKeys = (): readonly [\"sudojo\", \"solver\"] => {\n return solverQueryKeys.all();\n};\n"]}
1
+ {"version":3,"file":"query-keys.js","sourceRoot":"","sources":["../../../src/solver/hooks/query-keys.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,GAAG,GAAkC,EAAE,CACrD,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAEhC,MAAM,CAAC,MAAM,eAAe,GAAG;IAE7B,GAAG,EAAE,UAAU;IAMf,KAAK,EAAE,CAAC,OAOP,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,CAAU;IAMlD,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAC7B,CAAC,GAAG,UAAU,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAU;IAMlD,QAAQ,EAAE,CAAC,OAA+C,EAAE,EAAE,CAC5D,CAAC,GAAG,UAAU,EAAE,EAAE,UAAU,EAAE,OAAO,CAAU;CACzC,CAAC;AAaX,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAkC,EAAE;IACtE,OAAO,eAAe,CAAC,GAAG,EAAE,CAAC;AAC/B,CAAC,CAAC","sourcesContent":["/**\n * Query Key Factory for Sudojo Solver TanStack Query\n *\n * Provides type-safe, consistent query keys for Solver API endpoints.\n * Following TanStack Query best practices for key structure.\n *\n * ## Key Hierarchy\n *\n * All solver keys start with `[\"sudojo\", \"solver\"]` as the root:\n * - `[\"sudojo\", \"solver\", \"solve\", { original, user, ... }]` - solve hints\n * - `[\"sudojo\", \"solver\", \"validate\", originalPuzzle]` - validation\n * - `[\"sudojo\", \"solver\", \"generate\", { symmetrical }]` - generation\n *\n * ## Invalidation\n *\n * Use `getSolverServiceKeys()` to invalidate all solver queries at once.\n * Individual solve/validate/generate keys include their parameters so\n * different inputs produce distinct cache entries.\n */\n\nconst solverBase = (): readonly [\"sudojo\", \"solver\"] =>\n [\"sudojo\", \"solver\"] as const;\n\nexport const solverQueryKeys = {\n /** Root key for all solver queries. Use for bulk invalidation. */\n all: solverBase,\n\n /**\n * Key for a solve hints query. Includes all puzzle state parameters\n * so different board states produce separate cache entries.\n */\n solve: (options: {\n original: string;\n user: string;\n autoPencilmarks?: boolean | undefined;\n pencilmarks?: string | undefined;\n filters?: string | undefined;\n techniques?: string | undefined;\n }) => [...solverBase(), \"solve\", options] as const,\n\n /**\n * Key for a puzzle validation query. Since validation is deterministic\n * for a given original puzzle string, only the puzzle string is needed.\n */\n validate: (original: string) =>\n [...solverBase(), \"validate\", original] as const,\n\n /**\n * Key for a puzzle generation query. Includes symmetry preference\n * as different options may produce different puzzle types.\n */\n generate: (options?: { symmetrical?: boolean | undefined }) =>\n [...solverBase(), \"generate\", options] as const,\n} as const;\n\n/**\n * Helper to get the root key for all solver service queries.\n * Useful for bulk invalidation of the entire solver cache.\n *\n * @returns The root query key `[\"sudojo\", \"solver\"]`\n *\n * @example\n * ```ts\n * queryClient.invalidateQueries({ queryKey: getSolverServiceKeys() });\n * ```\n */\nexport const getSolverServiceKeys = (): readonly [\"sudojo\", \"solver\"] => {\n return solverQueryKeys.all();\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-solver.d.ts","sourceRoot":"","sources":["../../../src/solver/hooks/use-solver.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,YAAY,EACb,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAerC,eAAO,MAAM,cAAc,GACzB,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,SAAS,YAAY,EACrB,eAAe,IAAI,CACjB,eAAe,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EACxC,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,CA2BxC,CAAC;AAeF,eAAO,MAAM,iBAAiB,GAC5B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,SAAS,eAAe,EACxB,eAAe,IAAI,CACjB,eAAe,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAC3C,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAqB3C,CAAC;AAeF,eAAO,MAAM,iBAAiB,GAC5B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAS,eAAoB,EAC7B,eAAe,IAAI,CACjB,eAAe,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAC3C,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAqB3C,CAAC"}
1
+ {"version":3,"file":"use-solver.d.ts","sourceRoot":"","sources":["../../../src/solver/hooks/use-solver.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,YAAY,EACb,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAerC,eAAO,MAAM,cAAc,GACzB,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,SAAS,YAAY,EACrB,eAAe,IAAI,CACjB,eAAe,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,EACxC,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,CA4BxC,CAAC;AAeF,eAAO,MAAM,iBAAiB,GAC5B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,SAAS,eAAe,EACxB,eAAe,IAAI,CACjB,eAAe,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAC3C,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAqB3C,CAAC;AAeF,eAAO,MAAM,iBAAiB,GAC5B,eAAe,aAAa,EAC5B,SAAS,MAAM,EACf,OAAO,MAAM,EACb,UAAS,eAAoB,EAC7B,eAAe,IAAI,CACjB,eAAe,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EAC3C,UAAU,GAAG,SAAS,CACvB,KACA,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAqB3C,CAAC"}
@@ -17,6 +17,7 @@ export const useSolverSolve = (networkClient, baseUrl, token, options, queryOpti
17
17
  autoPencilmarks: options.autoPencilmarks,
18
18
  pencilmarks: options.pencilmarks,
19
19
  filters: options.filters,
20
+ techniques: options.techniques,
20
21
  }),
21
22
  queryFn,
22
23
  staleTime: SOLVER_STALE_TIMES.SOLVE,
@@ -1 +1 @@
1
- {"version":3,"file":"use-solver.js","sourceRoot":"","sources":["../../../src/solver/hooks/use-solver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React hooks for Sudojo Solver API\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport {\n useQuery,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { NetworkClient } from \"@sudobility/types\";\nimport type {\n BaseResponse,\n GenerateData,\n SolveData,\n ValidateData,\n} from \"@sudobility/sudojo_types\";\nimport { solverQueryKeys } from \"./query-keys\";\nimport { SOLVER_STALE_TIMES } from \"./query-config\";\nimport { SudojoClient } from \"../../network/sudojo-client\";\nimport type {\n GenerateOptions,\n SolveOptions,\n ValidateOptions,\n} from \"../../network/sudojo-client\";\n\n// =============================================================================\n// Solve Hook\n// =============================================================================\n\n/**\n * Hook to get solving hints for a Sudoku puzzle\n *\n * @param networkClient - Network client for API calls\n * @param baseUrl - Base URL for the API\n * @param token - Firebase access token\n * @param options - Solve options (original puzzle, user input, etc.)\n * @param queryOptions - React Query options\n */\nexport const useSolverSolve = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options: SolveOptions,\n queryOptions?: Omit<\n UseQueryOptions<BaseResponse<SolveData>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<SolveData>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<SolveData>> => {\n return client.solverSolve(token, options);\n }, [client, token, options]);\n\n const isEnabled =\n !!token &&\n (queryOptions?.enabled !== undefined ? queryOptions.enabled : true);\n\n return useQuery({\n queryKey: solverQueryKeys.solve({\n original: options.original,\n user: options.user,\n autoPencilmarks: options.autoPencilmarks,\n pencilmarks: options.pencilmarks,\n filters: options.filters,\n }),\n queryFn,\n staleTime: SOLVER_STALE_TIMES.SOLVE,\n ...queryOptions,\n enabled: isEnabled,\n });\n};\n\n// =============================================================================\n// Validate Hook\n// =============================================================================\n\n/**\n * Hook to validate a Sudoku puzzle has a unique solution\n *\n * @param networkClient - Network client for API calls\n * @param baseUrl - Base URL for the API\n * @param token - Firebase access token\n * @param options - Validate options (original puzzle)\n * @param queryOptions - React Query options\n */\nexport const useSolverValidate = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options: ValidateOptions,\n queryOptions?: Omit<\n UseQueryOptions<BaseResponse<ValidateData>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<ValidateData>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<ValidateData>> => {\n return client.solverValidate(token, options);\n }, [client, token, options]);\n\n // Validate endpoint does not require authentication\n const isEnabled =\n queryOptions?.enabled !== undefined ? queryOptions.enabled : true;\n\n return useQuery({\n queryKey: solverQueryKeys.validate(options.original),\n queryFn,\n staleTime: SOLVER_STALE_TIMES.VALIDATE,\n ...queryOptions,\n enabled: isEnabled,\n });\n};\n\n// =============================================================================\n// Generate Hook\n// =============================================================================\n\n/**\n * Hook to generate a new random Sudoku puzzle\n *\n * @param networkClient - Network client for API calls\n * @param baseUrl - Base URL for the API\n * @param token - Firebase access token\n * @param options - Generate options (symmetrical, etc.)\n * @param queryOptions - React Query options\n */\nexport const useSolverGenerate = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options: GenerateOptions = {},\n queryOptions?: Omit<\n UseQueryOptions<BaseResponse<GenerateData>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<GenerateData>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<GenerateData>> => {\n return client.solverGenerate(token, options);\n }, [client, token, options]);\n\n const isEnabled =\n !!token &&\n (queryOptions?.enabled !== undefined ? queryOptions.enabled : true);\n\n return useQuery({\n queryKey: solverQueryKeys.generate({ symmetrical: options.symmetrical }),\n queryFn,\n staleTime: SOLVER_STALE_TIMES.GENERATE,\n ...queryOptions,\n enabled: isEnabled,\n });\n};\n"]}
1
+ {"version":3,"file":"use-solver.js","sourceRoot":"","sources":["../../../src/solver/hooks/use-solver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React hooks for Sudojo Solver API\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport {\n useQuery,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { NetworkClient } from \"@sudobility/types\";\nimport type {\n BaseResponse,\n GenerateData,\n SolveData,\n ValidateData,\n} from \"@sudobility/sudojo_types\";\nimport { solverQueryKeys } from \"./query-keys\";\nimport { SOLVER_STALE_TIMES } from \"./query-config\";\nimport { SudojoClient } from \"../../network/sudojo-client\";\nimport type {\n GenerateOptions,\n SolveOptions,\n ValidateOptions,\n} from \"../../network/sudojo-client\";\n\n// =============================================================================\n// Solve Hook\n// =============================================================================\n\n/**\n * Hook to get solving hints for a Sudoku puzzle\n *\n * @param networkClient - Network client for API calls\n * @param baseUrl - Base URL for the API\n * @param token - Firebase access token\n * @param options - Solve options (original puzzle, user input, etc.)\n * @param queryOptions - React Query options\n */\nexport const useSolverSolve = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options: SolveOptions,\n queryOptions?: Omit<\n UseQueryOptions<BaseResponse<SolveData>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<SolveData>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<SolveData>> => {\n return client.solverSolve(token, options);\n }, [client, token, options]);\n\n const isEnabled =\n !!token &&\n (queryOptions?.enabled !== undefined ? queryOptions.enabled : true);\n\n return useQuery({\n queryKey: solverQueryKeys.solve({\n original: options.original,\n user: options.user,\n autoPencilmarks: options.autoPencilmarks,\n pencilmarks: options.pencilmarks,\n filters: options.filters,\n techniques: options.techniques,\n }),\n queryFn,\n staleTime: SOLVER_STALE_TIMES.SOLVE,\n ...queryOptions,\n enabled: isEnabled,\n });\n};\n\n// =============================================================================\n// Validate Hook\n// =============================================================================\n\n/**\n * Hook to validate a Sudoku puzzle has a unique solution\n *\n * @param networkClient - Network client for API calls\n * @param baseUrl - Base URL for the API\n * @param token - Firebase access token\n * @param options - Validate options (original puzzle)\n * @param queryOptions - React Query options\n */\nexport const useSolverValidate = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options: ValidateOptions,\n queryOptions?: Omit<\n UseQueryOptions<BaseResponse<ValidateData>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<ValidateData>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<ValidateData>> => {\n return client.solverValidate(token, options);\n }, [client, token, options]);\n\n // Validate endpoint does not require authentication\n const isEnabled =\n queryOptions?.enabled !== undefined ? queryOptions.enabled : true;\n\n return useQuery({\n queryKey: solverQueryKeys.validate(options.original),\n queryFn,\n staleTime: SOLVER_STALE_TIMES.VALIDATE,\n ...queryOptions,\n enabled: isEnabled,\n });\n};\n\n// =============================================================================\n// Generate Hook\n// =============================================================================\n\n/**\n * Hook to generate a new random Sudoku puzzle\n *\n * @param networkClient - Network client for API calls\n * @param baseUrl - Base URL for the API\n * @param token - Firebase access token\n * @param options - Generate options (symmetrical, etc.)\n * @param queryOptions - React Query options\n */\nexport const useSolverGenerate = (\n networkClient: NetworkClient,\n baseUrl: string,\n token: string,\n options: GenerateOptions = {},\n queryOptions?: Omit<\n UseQueryOptions<BaseResponse<GenerateData>>,\n \"queryKey\" | \"queryFn\"\n >,\n): UseQueryResult<BaseResponse<GenerateData>> => {\n const client = useMemo(\n () => new SudojoClient(networkClient, baseUrl),\n [networkClient, baseUrl],\n );\n\n const queryFn = useCallback(async (): Promise<BaseResponse<GenerateData>> => {\n return client.solverGenerate(token, options);\n }, [client, token, options]);\n\n const isEnabled =\n !!token &&\n (queryOptions?.enabled !== undefined ? queryOptions.enabled : true);\n\n return useQuery({\n queryKey: solverQueryKeys.generate({ symmetrical: options.symmetrical }),\n queryFn,\n staleTime: SOLVER_STALE_TIMES.GENERATE,\n ...queryOptions,\n enabled: isEnabled,\n });\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/sudojo_client",
3
- "version": "0.0.104",
3
+ "version": "0.0.106",
4
4
  "description": "TypeScript client library for Sudojo API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "license": "BUSL-1.1",
38
38
  "peerDependencies": {
39
39
  "@sudobility/di": "^1.5.56",
40
- "@sudobility/sudojo_types": "^1.2.51",
40
+ "@sudobility/sudojo_types": "^1.2.52",
41
41
  "@sudobility/types": "^1.9.62",
42
42
  "@tanstack/react-query": ">=5.0.0",
43
43
  "react": ">=18.0.0"
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@eslint/js": "^9.38.0",
47
47
  "@sudobility/di": "^1.5.56",
48
- "@sudobility/sudojo_types": "^1.2.51",
48
+ "@sudobility/sudojo_types": "^1.2.52",
49
49
  "@sudobility/types": "^1.9.62",
50
50
  "@tanstack/react-query": "^5.90.5",
51
51
  "@testing-library/react": "^16.3.0",