@sudobility/sudojo_lib 0.0.130 → 0.0.131
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.
|
@@ -47,14 +47,16 @@ export declare function onHintStatus(listener: HintStatusListener): () => void;
|
|
|
47
47
|
* - If hint is showing and has next step, calls nextStep()
|
|
48
48
|
* - Reports status back via reportHintStatus()
|
|
49
49
|
*/
|
|
50
|
-
export declare function useHintActionListener({ hint, hints, stepIndex, totalSteps, hasNextStep, getHint, nextStep, deselectCell, }: {
|
|
50
|
+
export declare function useHintActionListener({ hint, hints, stepIndex, totalSteps, hasNextStep, canApply, getHint, nextStep, applyHint, deselectCell, }: {
|
|
51
51
|
hint: unknown | null;
|
|
52
52
|
hints: unknown[] | null;
|
|
53
53
|
stepIndex: number;
|
|
54
54
|
totalSteps: number;
|
|
55
55
|
hasNextStep: boolean;
|
|
56
|
+
canApply: boolean;
|
|
56
57
|
getHint: () => void;
|
|
57
58
|
nextStep: () => void;
|
|
59
|
+
applyHint: () => void;
|
|
58
60
|
deselectCell: () => void;
|
|
59
61
|
}): void;
|
|
60
62
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHintAction.d.ts","sourceRoot":"","sources":["../../src/hooks/useHintAction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,UAAU,EAAE,OAAO,CAAC;IACpB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,mFAAmF;IACnF,SAAS,EAAE,OAAO,CAAC;CACpB;AAGD,KAAK,kBAAkB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAQ7D;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAIrC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAI/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAGrE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAW,EACX,OAAO,EACP,QAAQ,EACR,YAAY,GACb,EAAE;IACD,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"useHintAction.d.ts","sourceRoot":"","sources":["../../src/hooks/useHintAction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,UAAU,EAAE,OAAO,CAAC;IACpB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,mFAAmF;IACnF,SAAS,EAAE,OAAO,CAAC;CACpB;AAGD,KAAK,kBAAkB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAQ7D;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAIrC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAI/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAGrE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,YAAY,GACb,EAAE;IACD,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,GAAG,IAAI,CAsEP"}
|
|
@@ -49,7 +49,7 @@ export function onHintStatus(listener) {
|
|
|
49
49
|
* - If hint is showing and has next step, calls nextStep()
|
|
50
50
|
* - Reports status back via reportHintStatus()
|
|
51
51
|
*/
|
|
52
|
-
export function useHintActionListener({ hint, hints, stepIndex, totalSteps, hasNextStep, getHint, nextStep, deselectCell, }) {
|
|
52
|
+
export function useHintActionListener({ hint, hints, stepIndex, totalSteps, hasNextStep, canApply, getHint, nextStep, applyHint, deselectCell, }) {
|
|
53
53
|
// Use refs to avoid stale closures in the listener
|
|
54
54
|
const stateRef = useRef({
|
|
55
55
|
hint,
|
|
@@ -57,15 +57,23 @@ export function useHintActionListener({ hint, hints, stepIndex, totalSteps, hasN
|
|
|
57
57
|
stepIndex,
|
|
58
58
|
totalSteps,
|
|
59
59
|
hasNextStep,
|
|
60
|
+
canApply,
|
|
60
61
|
});
|
|
61
|
-
stateRef.current = {
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
stateRef.current = {
|
|
63
|
+
hint,
|
|
64
|
+
hints,
|
|
65
|
+
stepIndex,
|
|
66
|
+
totalSteps,
|
|
67
|
+
hasNextStep,
|
|
68
|
+
canApply,
|
|
69
|
+
};
|
|
70
|
+
const actionsRef = useRef({ getHint, nextStep, applyHint, deselectCell });
|
|
71
|
+
actionsRef.current = { getHint, nextStep, applyHint, deselectCell };
|
|
64
72
|
// Track if we just triggered an action and need to report status after state updates
|
|
65
73
|
const pendingStatusRef = useRef(false);
|
|
66
74
|
const handleAction = useCallback(() => {
|
|
67
|
-
const { hint: h, hasNextStep: hasNext } = stateRef.current;
|
|
68
|
-
const { getHint: doGetHint, nextStep: doNextStep, deselectCell: doDeselect, } = actionsRef.current;
|
|
75
|
+
const { hint: h, hasNextStep: hasNext, canApply: canDo } = stateRef.current;
|
|
76
|
+
const { getHint: doGetHint, nextStep: doNextStep, applyHint: doApply, deselectCell: doDeselect, } = actionsRef.current;
|
|
69
77
|
if (h === null) {
|
|
70
78
|
// No hint showing — trigger hint fetch
|
|
71
79
|
doDeselect();
|
|
@@ -75,7 +83,10 @@ export function useHintActionListener({ hint, hints, stepIndex, totalSteps, hasN
|
|
|
75
83
|
// Hint showing, advance to next step
|
|
76
84
|
doNextStep();
|
|
77
85
|
}
|
|
78
|
-
|
|
86
|
+
else if (canDo) {
|
|
87
|
+
// On last step — apply the hint
|
|
88
|
+
doApply();
|
|
89
|
+
}
|
|
79
90
|
pendingStatusRef.current = true;
|
|
80
91
|
}, []);
|
|
81
92
|
// Register/unregister the action listener
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHintAction.js","sourceRoot":"","sources":["../../src/hooks/useHintAction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAmBvD,qEAAqE;AACrE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEtD,+EAA+E;AAC/E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAwB;IACvD,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAA4B;IACvD,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAW,EACX,OAAO,EACP,QAAQ,EACR,YAAY,
|
|
1
|
+
{"version":3,"file":"useHintAction.js","sourceRoot":"","sources":["../../src/hooks/useHintAction.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hint action event system for external control of the hint UI.\n *\n * Used by deep links (e.g., sudojo:///en/action/hint) to trigger hint actions\n * on the currently active SudokuGame without navigating to a new screen.\n *\n * Flow:\n * 1. Deep link handler calls `emitHintAction()`\n * 2. The active SudokuGame's `useHintActionListener` receives the event\n * 3. It calls getHint() or nextStep() as appropriate\n * 4. After processing, it calls the status callback so the emitter knows\n * what happened (e.g., hint completed, step advanced)\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\n/** Status reported back after a hint action is processed */\nexport interface HintActionStatus {\n /** Whether a hint is currently showing */\n hintActive: boolean;\n /** Current step index (0-based) */\n stepIndex: number;\n /** Total number of steps */\n totalSteps: number;\n /** Whether there are more steps */\n hasNextStep: boolean;\n /** Whether the hint has been fully stepped through (on last step, no more next) */\n completed: boolean;\n}\n\ntype HintActionListener = () => void;\ntype HintStatusListener = (status: HintActionStatus) => void;\n\n/** Registered action listeners (from active SudokuGame instances) */\nconst actionListeners = new Set<HintActionListener>();\n\n/** Registered status listeners (from the script/caller waiting for results) */\nconst statusListeners = new Set<HintStatusListener>();\n\n/**\n * Emit a hint action event. The active SudokuGame will receive this\n * and trigger getHint() or nextStep().\n */\nexport function emitHintAction(): void {\n for (const listener of actionListeners) {\n listener();\n }\n}\n\n/**\n * Report hint status back to any listeners (e.g., the recording script).\n */\nexport function reportHintStatus(status: HintActionStatus): void {\n for (const listener of statusListeners) {\n listener(status);\n }\n}\n\n/**\n * Subscribe to hint status updates.\n * Returns an unsubscribe function.\n */\nexport function onHintStatus(listener: HintStatusListener): () => void {\n statusListeners.add(listener);\n return () => statusListeners.delete(listener);\n}\n\n/**\n * Hook for SudokuGame to listen for external hint action events.\n *\n * When an event is received:\n * - If no hint is showing, calls getHint()\n * - If hint is showing and has next step, calls nextStep()\n * - Reports status back via reportHintStatus()\n */\nexport function useHintActionListener({\n hint,\n hints,\n stepIndex,\n totalSteps,\n hasNextStep,\n canApply,\n getHint,\n nextStep,\n applyHint,\n deselectCell,\n}: {\n hint: unknown | null;\n hints: unknown[] | null;\n stepIndex: number;\n totalSteps: number;\n hasNextStep: boolean;\n canApply: boolean;\n getHint: () => void;\n nextStep: () => void;\n applyHint: () => void;\n deselectCell: () => void;\n}): void {\n // Use refs to avoid stale closures in the listener\n const stateRef = useRef({\n hint,\n hints,\n stepIndex,\n totalSteps,\n hasNextStep,\n canApply,\n });\n stateRef.current = {\n hint,\n hints,\n stepIndex,\n totalSteps,\n hasNextStep,\n canApply,\n };\n\n const actionsRef = useRef({ getHint, nextStep, applyHint, deselectCell });\n actionsRef.current = { getHint, nextStep, applyHint, deselectCell };\n\n // Track if we just triggered an action and need to report status after state updates\n const pendingStatusRef = useRef(false);\n\n const handleAction = useCallback(() => {\n const { hint: h, hasNextStep: hasNext, canApply: canDo } = stateRef.current;\n const {\n getHint: doGetHint,\n nextStep: doNextStep,\n applyHint: doApply,\n deselectCell: doDeselect,\n } = actionsRef.current;\n\n if (h === null) {\n // No hint showing — trigger hint fetch\n doDeselect();\n doGetHint();\n } else if (hasNext) {\n // Hint showing, advance to next step\n doNextStep();\n } else if (canDo) {\n // On last step — apply the hint\n doApply();\n }\n\n pendingStatusRef.current = true;\n }, []);\n\n // Register/unregister the action listener\n useEffect(() => {\n actionListeners.add(handleAction);\n return () => {\n actionListeners.delete(handleAction);\n };\n }, [handleAction]);\n\n // Report status whenever hint state changes after an action\n useEffect(() => {\n if (pendingStatusRef.current) {\n pendingStatusRef.current = false;\n reportHintStatus({\n hintActive: hint !== null,\n stepIndex,\n totalSteps,\n hasNextStep,\n completed: hint !== null && !hasNextStep,\n });\n }\n }, [hint, stepIndex, totalSteps, hasNextStep]);\n}\n"]}
|