@pompidup/kingdomino-engine 2.0.3 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -23
- package/dist/index.d.ts +11 -35
- package/dist/index.js +200 -46
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -658,6 +658,57 @@ var jsonRules = () => {
|
|
|
658
658
|
};
|
|
659
659
|
var jsonRules_default = jsonRules;
|
|
660
660
|
|
|
661
|
+
// src/adapterServerside/shuffle.ts
|
|
662
|
+
var shuffleMethod = (array) => {
|
|
663
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
664
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
665
|
+
[array[i], array[j]] = [array[j], array[i]];
|
|
666
|
+
}
|
|
667
|
+
return array;
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
// src/adapterServerside/uuid.ts
|
|
671
|
+
import { randomUUID } from "crypto";
|
|
672
|
+
var uuidMethod = () => {
|
|
673
|
+
return randomUUID();
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
// src/adapterServerside/winstonLogger.ts
|
|
677
|
+
import winston from "winston";
|
|
678
|
+
var winstonLogger = (isLoggingEnabled) => {
|
|
679
|
+
const myFormat = winston.format.printf(
|
|
680
|
+
({ level, message, label, timestamp }) => {
|
|
681
|
+
return `${timestamp} [${label}] ${level}: ${message}`;
|
|
682
|
+
}
|
|
683
|
+
);
|
|
684
|
+
const logger = winston.createLogger({
|
|
685
|
+
level: "info",
|
|
686
|
+
format: winston.format.combine(
|
|
687
|
+
winston.format.label({ label: "KDomino_Engine" }),
|
|
688
|
+
winston.format.timestamp(),
|
|
689
|
+
winston.format.simple(),
|
|
690
|
+
winston.format.json(),
|
|
691
|
+
winston.format.colorize(),
|
|
692
|
+
myFormat
|
|
693
|
+
),
|
|
694
|
+
transports: [new winston.transports.Console()]
|
|
695
|
+
});
|
|
696
|
+
return {
|
|
697
|
+
info: (message) => {
|
|
698
|
+
if (isLoggingEnabled) {
|
|
699
|
+
logger.info(message);
|
|
700
|
+
}
|
|
701
|
+
return void 0;
|
|
702
|
+
},
|
|
703
|
+
error: (message) => {
|
|
704
|
+
if (isLoggingEnabled) {
|
|
705
|
+
logger.error(message);
|
|
706
|
+
}
|
|
707
|
+
return void 0;
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
};
|
|
711
|
+
|
|
661
712
|
// src/core/domain/errors/domainErrors.ts
|
|
662
713
|
var InvalidStepError = class extends Error {
|
|
663
714
|
constructor(message) {
|
|
@@ -684,6 +735,20 @@ var NotFoundError = class extends Error {
|
|
|
684
735
|
}
|
|
685
736
|
};
|
|
686
737
|
|
|
738
|
+
// src/core/domain/types/game.ts
|
|
739
|
+
var gameSteps = {
|
|
740
|
+
addPlayers: "addPlayers",
|
|
741
|
+
options: "options",
|
|
742
|
+
start: "start",
|
|
743
|
+
result: "result"
|
|
744
|
+
};
|
|
745
|
+
var isGameWithNextAction = (game) => {
|
|
746
|
+
return game.nextAction.type === "action";
|
|
747
|
+
};
|
|
748
|
+
var isGameWithNextStep = (game) => {
|
|
749
|
+
return game.nextAction.type === "step";
|
|
750
|
+
};
|
|
751
|
+
|
|
687
752
|
// src/utils/result.ts
|
|
688
753
|
var ok = (value) => ({ tag: "Ok", value });
|
|
689
754
|
var err = (error) => ({ tag: "Err", error });
|
|
@@ -691,140 +756,235 @@ var isOk = (result) => result.tag === "Ok";
|
|
|
691
756
|
var isErr = (result) => result.tag === "Err";
|
|
692
757
|
|
|
693
758
|
// src/application/handlers/addExtraRulesHandler.ts
|
|
694
|
-
var addExtraRulesHandler = (useCase) => (command) => {
|
|
759
|
+
var addExtraRulesHandler = (logger, useCase) => (command) => {
|
|
695
760
|
const { game, extraRules } = command;
|
|
761
|
+
logger.info(`Adding extra rules to game: ${game.id}`);
|
|
762
|
+
logger.info(`Extra rules: ${extraRules}`);
|
|
763
|
+
if (!isGameWithNextStep(game)) {
|
|
764
|
+
logger.error("Invalid game with nextAction type: 'step'");
|
|
765
|
+
throw new InvalidStepError("Required game with nextAction type: 'step'");
|
|
766
|
+
}
|
|
696
767
|
if (game.nextAction.step !== "options") {
|
|
768
|
+
logger.error(
|
|
769
|
+
`Required game with options step but got: ${game.nextAction.step}`
|
|
770
|
+
);
|
|
697
771
|
throw new InvalidStepError("Required game with options step");
|
|
698
772
|
}
|
|
699
773
|
const result = useCase(game, extraRules);
|
|
700
774
|
if (isErr(result)) {
|
|
775
|
+
logger.error(`Error adding extra rules: ${result.error}`);
|
|
701
776
|
throw new StepExecutionError(result.error);
|
|
702
777
|
}
|
|
778
|
+
logger.info(`Extra rules added to game: ${game.id}`);
|
|
703
779
|
return result.value;
|
|
704
780
|
};
|
|
705
781
|
|
|
706
782
|
// src/application/handlers/addPlayersHandler.ts
|
|
707
|
-
var addPlayersHandler = (useCase) => (command) => {
|
|
783
|
+
var addPlayersHandler = (logger, useCase) => (command) => {
|
|
708
784
|
const { game, players } = command;
|
|
785
|
+
logger.info(`Adding players to game: ${game.id}`);
|
|
786
|
+
if (!isGameWithNextStep(game)) {
|
|
787
|
+
logger.error("Invalid game with nextAction type: 'step'");
|
|
788
|
+
throw new InvalidStepError("Required game with nextAction type: 'step'");
|
|
789
|
+
}
|
|
709
790
|
if (game.nextAction.step !== "addPlayers") {
|
|
791
|
+
logger.error(
|
|
792
|
+
`Required game with addPlayers step but got: ${game.nextAction.step}`
|
|
793
|
+
);
|
|
710
794
|
throw new InvalidStepError("Required game with addPlayers step");
|
|
711
795
|
}
|
|
712
796
|
const result = useCase(game, players);
|
|
713
797
|
if (isErr(result)) {
|
|
798
|
+
logger.error(`Error adding players: ${result.error}`);
|
|
714
799
|
throw new StepExecutionError(result.error);
|
|
715
800
|
}
|
|
801
|
+
logger.info(`Players added to game: ${game.id}`);
|
|
716
802
|
return result.value;
|
|
717
803
|
};
|
|
718
804
|
|
|
719
805
|
// src/application/handlers/chooseDominoHandler.ts
|
|
720
|
-
var chooseDominoHandler = (useCase) => (command) => {
|
|
806
|
+
var chooseDominoHandler = (logger, useCase) => (command) => {
|
|
721
807
|
const { game, lordId, dominoPick } = command;
|
|
808
|
+
logger.info(
|
|
809
|
+
`Choosing domino: ${dominoPick} for lord: ${lordId} in game: ${game.id}`
|
|
810
|
+
);
|
|
811
|
+
if (!isGameWithNextAction(game)) {
|
|
812
|
+
logger.error("Invalid game with nextAction type: 'action'");
|
|
813
|
+
throw new InvalidStepError(
|
|
814
|
+
"Required game with nextAction type: 'action'"
|
|
815
|
+
);
|
|
816
|
+
}
|
|
722
817
|
if (game.nextAction.nextAction !== "pickDomino") {
|
|
818
|
+
logger.error(
|
|
819
|
+
`Required game with pickDomino action but got: ${game.nextAction.nextAction}`
|
|
820
|
+
);
|
|
723
821
|
throw new InvalidStepError("Required game with pickDomino action");
|
|
724
822
|
}
|
|
725
823
|
const result = useCase(game, lordId, dominoPick);
|
|
726
824
|
if (isErr(result)) {
|
|
825
|
+
logger.error(`Error choosing domino: ${result.error}`);
|
|
727
826
|
throw new ActionExecutionError(result.error);
|
|
728
827
|
}
|
|
828
|
+
logger.info(
|
|
829
|
+
`Domino chosen: ${dominoPick} for lord: ${lordId} in game: ${game.id}`
|
|
830
|
+
);
|
|
729
831
|
return result.value;
|
|
730
832
|
};
|
|
731
833
|
|
|
732
834
|
// src/application/handlers/createGameHandler.ts
|
|
733
|
-
var createGameHandler = (useCase) => (command) => {
|
|
835
|
+
var createGameHandler = (logger, useCase) => (command) => {
|
|
836
|
+
logger.info(`Creating game with mode: ${command.mode}`);
|
|
734
837
|
const result = useCase(command.mode);
|
|
735
838
|
if (isErr(result)) {
|
|
839
|
+
logger.error(`Error creating game: ${result.error}`);
|
|
736
840
|
throw new StepExecutionError(result.error);
|
|
737
841
|
}
|
|
842
|
+
logger.info(`Game created: ${result.value.id}`);
|
|
738
843
|
return result.value;
|
|
739
844
|
};
|
|
740
845
|
|
|
741
|
-
// src/core/domain/types/game.ts
|
|
742
|
-
var gameSteps = {
|
|
743
|
-
addPlayers: "addPlayers",
|
|
744
|
-
options: "options",
|
|
745
|
-
start: "start",
|
|
746
|
-
result: "result"
|
|
747
|
-
};
|
|
748
|
-
var isGameWithNextAction = (game) => {
|
|
749
|
-
return game.nextAction.type === "action";
|
|
750
|
-
};
|
|
751
|
-
|
|
752
846
|
// src/application/handlers/discardDominoHandler.ts
|
|
753
|
-
var discardDominoHandler = (useCase) => (command) => {
|
|
847
|
+
var discardDominoHandler = (logger, useCase) => (command) => {
|
|
754
848
|
const { game, lordId } = command;
|
|
849
|
+
logger.info(`Discarding domino for lord: ${lordId} in game: ${game.id}`);
|
|
850
|
+
if (!isGameWithNextAction(game)) {
|
|
851
|
+
logger.error("Invalid game with nextAction type: 'action'");
|
|
852
|
+
throw new InvalidStepError(
|
|
853
|
+
"Required game with nextAction type: 'action'"
|
|
854
|
+
);
|
|
855
|
+
}
|
|
755
856
|
if (game.nextAction.nextAction !== "placeDomino") {
|
|
857
|
+
logger.error(
|
|
858
|
+
`Required game with placeDomino action but got: ${game.nextAction.nextAction}`
|
|
859
|
+
);
|
|
756
860
|
throw new InvalidStepError("Required game with placeDomino action");
|
|
757
861
|
}
|
|
758
862
|
const result = useCase(game, lordId);
|
|
759
863
|
if (isErr(result)) {
|
|
864
|
+
logger.error(`Error discarding domino: ${result.error}`);
|
|
760
865
|
throw new ActionExecutionError(result.error);
|
|
761
866
|
}
|
|
762
867
|
if (isGameWithNextAction(result.value)) {
|
|
868
|
+
logger.info(`Domino discarded: ${lordId} in game: ${game.id}`);
|
|
763
869
|
return result.value;
|
|
764
870
|
}
|
|
871
|
+
logger.info(`Domino discarded: ${lordId} in game: ${game.id}`);
|
|
765
872
|
return result.value;
|
|
766
873
|
};
|
|
767
874
|
|
|
768
875
|
// src/application/handlers/getExtraRulesHandler.ts
|
|
769
|
-
var getExtraRulesHandler = (
|
|
876
|
+
var getExtraRulesHandler = (logger, useCase) => (command) => {
|
|
770
877
|
const { mode, players } = command;
|
|
771
|
-
|
|
878
|
+
logger.info(
|
|
879
|
+
`Getting extra rules for mode: ${mode} and players: ${players}`
|
|
880
|
+
);
|
|
881
|
+
const result = useCase(mode, players);
|
|
772
882
|
if (isErr(result)) {
|
|
883
|
+
logger.error(`Error getting extra rules: ${result.error}`);
|
|
773
884
|
throw new NotFoundError(result.error);
|
|
774
885
|
}
|
|
886
|
+
logger.info(`Extra rules retrieved: ${result.value}`);
|
|
775
887
|
return result.value;
|
|
776
888
|
};
|
|
777
889
|
|
|
778
890
|
// src/application/handlers/getModesHandler.ts
|
|
779
|
-
var getModesHandler = (
|
|
780
|
-
|
|
891
|
+
var getModesHandler = (logger, useCase) => (_command) => {
|
|
892
|
+
logger.info("Getting modes");
|
|
893
|
+
const result = useCase();
|
|
781
894
|
if (isErr(result)) {
|
|
895
|
+
logger.error(`Error getting modes: ${result.error}`);
|
|
782
896
|
throw new NotFoundError(result.error);
|
|
783
897
|
}
|
|
898
|
+
logger.info(`Modes retrieved: ${result.value}`);
|
|
784
899
|
return result.value;
|
|
785
900
|
};
|
|
786
901
|
|
|
787
902
|
// src/application/handlers/getResultHandler.ts
|
|
788
|
-
var getResultHandler = (useCase) => (command) => {
|
|
903
|
+
var getResultHandler = (logger, useCase) => (command) => {
|
|
789
904
|
const { game } = command;
|
|
905
|
+
logger.info(`Getting result for game: ${game.id}`);
|
|
906
|
+
if (!isGameWithNextStep(game)) {
|
|
907
|
+
logger.error("Invalid game with nextAction type: 'step'");
|
|
908
|
+
throw new InvalidStepError("Required game with nextAction type: 'step'");
|
|
909
|
+
}
|
|
790
910
|
if (game.nextAction.step !== "result") {
|
|
911
|
+
logger.error(
|
|
912
|
+
`Required game with result step but got: ${game.nextAction.step}`
|
|
913
|
+
);
|
|
791
914
|
throw new InvalidStepError("Required game with result step");
|
|
792
915
|
}
|
|
793
916
|
const result = useCase(game);
|
|
794
917
|
if (isErr(result)) {
|
|
918
|
+
logger.error(`Error getting result: ${result.error}`);
|
|
795
919
|
throw new NotFoundError(result.error);
|
|
796
920
|
}
|
|
921
|
+
logger.info(`Result retrieved for game: ${game.id}`);
|
|
797
922
|
return result.value;
|
|
798
923
|
};
|
|
799
924
|
|
|
800
925
|
// src/application/handlers/placeDominoHandler.ts
|
|
801
|
-
var placeDominoHandler = (useCase) => (command) => {
|
|
926
|
+
var placeDominoHandler = (logger, useCase) => (command) => {
|
|
802
927
|
const { game, lordId, position, orientation, rotation } = command;
|
|
928
|
+
logger.info(
|
|
929
|
+
`Placing domino: ${lordId} in position: ${JSON.stringify(
|
|
930
|
+
position
|
|
931
|
+
)} with orientation: ${orientation} and rotation: ${rotation} in game: ${game.id}`
|
|
932
|
+
);
|
|
933
|
+
if (!isGameWithNextAction(game)) {
|
|
934
|
+
logger.error("Invalid game with nextAction type: 'action'");
|
|
935
|
+
throw new InvalidStepError(
|
|
936
|
+
"Required game with nextAction type: 'action'"
|
|
937
|
+
);
|
|
938
|
+
}
|
|
803
939
|
if (game.nextAction.nextAction !== "placeDomino") {
|
|
940
|
+
logger.error(
|
|
941
|
+
`Required game with placeDomino action but got: ${game.nextAction.nextAction}`
|
|
942
|
+
);
|
|
804
943
|
throw new InvalidStepError("Required game with placeDomino step");
|
|
805
944
|
}
|
|
806
945
|
const result = useCase(game, lordId, position, orientation, rotation);
|
|
807
946
|
if (isErr(result)) {
|
|
947
|
+
logger.error(`Error placing domino: ${result.error}`);
|
|
808
948
|
throw new ActionExecutionError(result.error);
|
|
809
949
|
}
|
|
810
950
|
if (isGameWithNextAction(result.value)) {
|
|
951
|
+
logger.info(
|
|
952
|
+
`Domino placed: ${lordId} in position: ${JSON.stringify(
|
|
953
|
+
position
|
|
954
|
+
)} with orientation: ${orientation} and rotation: ${rotation} in game: ${game.id}`
|
|
955
|
+
);
|
|
811
956
|
return result.value;
|
|
812
957
|
}
|
|
958
|
+
logger.info(
|
|
959
|
+
`Domino placed: ${lordId} in position: ${JSON.stringify(
|
|
960
|
+
position
|
|
961
|
+
)} with orientation: ${orientation} and rotation: ${rotation} in game: ${game.id}`
|
|
962
|
+
);
|
|
813
963
|
return result.value;
|
|
814
964
|
};
|
|
815
965
|
|
|
816
966
|
// src/application/handlers/startGameHandler.ts
|
|
817
|
-
var startGameHandler = (useCase) => (command) => {
|
|
967
|
+
var startGameHandler = (logger, useCase) => (command) => {
|
|
818
968
|
const { game } = command;
|
|
969
|
+
logger.info(`Starting game: ${game.id}`);
|
|
970
|
+
if (!isGameWithNextStep(game)) {
|
|
971
|
+
logger.error("Invalid game with nextAction type: 'step'");
|
|
972
|
+
throw new InvalidStepError("Required game with nextAction type: 'step'");
|
|
973
|
+
}
|
|
819
974
|
if (game.nextAction.step !== "start" && game.nextAction.step !== "options") {
|
|
975
|
+
logger.error(
|
|
976
|
+
`Required game with start step or options step but got: ${game.nextAction.step}`
|
|
977
|
+
);
|
|
820
978
|
throw new InvalidStepError(
|
|
821
979
|
"Required game with start step or options step"
|
|
822
980
|
);
|
|
823
981
|
}
|
|
824
982
|
const result = useCase(game);
|
|
825
983
|
if (isErr(result)) {
|
|
984
|
+
logger.error(`Error starting game: ${result.error}`);
|
|
826
985
|
throw new StepExecutionError(result.error);
|
|
827
986
|
}
|
|
987
|
+
logger.info(`Game started: ${game.id}`);
|
|
828
988
|
return result.value;
|
|
829
989
|
};
|
|
830
990
|
|
|
@@ -1727,41 +1887,33 @@ var startGameUseCase = (deps) => (game) => {
|
|
|
1727
1887
|
return ok(newState);
|
|
1728
1888
|
};
|
|
1729
1889
|
|
|
1730
|
-
// src/adapterServerside/shuffle.ts
|
|
1731
|
-
var shuffleMethod = (array) => {
|
|
1732
|
-
for (let i = array.length - 1; i > 0; i--) {
|
|
1733
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
1734
|
-
[array[i], array[j]] = [array[j], array[i]];
|
|
1735
|
-
}
|
|
1736
|
-
return array;
|
|
1737
|
-
};
|
|
1738
|
-
|
|
1739
|
-
// src/adapterServerside/uuid.ts
|
|
1740
|
-
import { randomUUID } from "crypto";
|
|
1741
|
-
var uuidMethod = () => {
|
|
1742
|
-
return randomUUID();
|
|
1743
|
-
};
|
|
1744
|
-
|
|
1745
1890
|
// src/config.ts
|
|
1746
1891
|
var configureEngine = (config) => {
|
|
1747
|
-
const modeRepository =
|
|
1748
|
-
const dominoesRepository =
|
|
1749
|
-
const ruleRepository =
|
|
1892
|
+
const modeRepository = jsonModes_default();
|
|
1893
|
+
const dominoesRepository = jsonDominoes_default();
|
|
1894
|
+
const ruleRepository = jsonRules_default();
|
|
1750
1895
|
const uuid = config.uuidMethod || uuidMethod;
|
|
1751
1896
|
const shuffle = config.shuffleMethod || shuffleMethod;
|
|
1897
|
+
const logger = config.logging ? winstonLogger(true) : winstonLogger(false);
|
|
1752
1898
|
return {
|
|
1753
1899
|
createGameHandler: createGameHandler(
|
|
1900
|
+
logger,
|
|
1754
1901
|
createGameUseCase({
|
|
1755
1902
|
modeRepository,
|
|
1756
1903
|
dominoesRepository,
|
|
1757
1904
|
uuidMethod: uuid
|
|
1758
1905
|
})
|
|
1759
1906
|
),
|
|
1760
|
-
getModesHandler: getModesHandler(
|
|
1907
|
+
getModesHandler: getModesHandler(
|
|
1908
|
+
logger,
|
|
1909
|
+
getModesUseCase({ modeRepository })
|
|
1910
|
+
),
|
|
1761
1911
|
getExtraRulesHandler: getExtraRulesHandler(
|
|
1912
|
+
logger,
|
|
1762
1913
|
getExtraRulesUseCase({ ruleRepository })
|
|
1763
1914
|
),
|
|
1764
1915
|
addPlayersHandler: addPlayersHandler(
|
|
1916
|
+
logger,
|
|
1765
1917
|
addPlayersUseCase({
|
|
1766
1918
|
uuidMethod: uuid,
|
|
1767
1919
|
shuffleMethod: shuffle,
|
|
@@ -1769,15 +1921,17 @@ var configureEngine = (config) => {
|
|
|
1769
1921
|
})
|
|
1770
1922
|
),
|
|
1771
1923
|
addExtraRulesHandler: addExtraRulesHandler(
|
|
1924
|
+
logger,
|
|
1772
1925
|
addExtraRulesUseCase({ ruleRepository })
|
|
1773
1926
|
),
|
|
1774
1927
|
startGameHandler: startGameHandler(
|
|
1928
|
+
logger,
|
|
1775
1929
|
startGameUseCase({ uuidMethod: uuid, shuffleMethod: shuffle })
|
|
1776
1930
|
),
|
|
1777
|
-
chooseDominoHandler: chooseDominoHandler(chooseDominoUseCase),
|
|
1778
|
-
placeDominoHandler: placeDominoHandler(placeDominoUseCase),
|
|
1779
|
-
discardDominoHandler: discardDominoHandler(discardDominoUseCase),
|
|
1780
|
-
getResultHandler: getResultHandler(getResultUseCase)
|
|
1931
|
+
chooseDominoHandler: chooseDominoHandler(logger, chooseDominoUseCase),
|
|
1932
|
+
placeDominoHandler: placeDominoHandler(logger, placeDominoUseCase),
|
|
1933
|
+
discardDominoHandler: discardDominoHandler(logger, discardDominoUseCase),
|
|
1934
|
+
getResultHandler: getResultHandler(logger, getResultUseCase)
|
|
1781
1935
|
};
|
|
1782
1936
|
};
|
|
1783
1937
|
|