wip
This commit is contained in:
parent
4e75fae835
commit
b4293b2736
@ -44,11 +44,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@reduxjs/toolkit": "==2.0.0-alpha.5 ",
|
"@reduxjs/toolkit": "==2.0.0-alpha.5 ",
|
||||||
"@yanick/updeep-remeda": "^2.2.0",
|
"@yanick/updeep-remeda": "^2.2.0",
|
||||||
|
"ajv": "^8.12.0",
|
||||||
"beercss": "^3.1.3",
|
"beercss": "^3.1.3",
|
||||||
"git-describe": "^4.1.1",
|
"git-describe": "^4.1.1",
|
||||||
"git-repo-version": "^1.0.2",
|
"git-repo-version": "^1.0.2",
|
||||||
"histoire": "^0.16.1",
|
"histoire": "^0.16.1",
|
||||||
"jsdom": "^21.1.1",
|
"jsdom": "^21.1.1",
|
||||||
|
"json-schema-shorthand": "^3.0.0",
|
||||||
|
"json-schema-to-ts": "^2.9.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mdsvex": "^0.10.6",
|
"mdsvex": "^0.10.6",
|
||||||
"memoize-one": "^6.0.0",
|
"memoize-one": "^6.0.0",
|
||||||
|
13
src/lib/jsc.ts
Normal file
13
src/lib/jsc.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export default {
|
||||||
|
string: (args = {}) => ({ type: "string" as const, ...args }),
|
||||||
|
object: <P extends {}, A extends {}>(properties: P = {}, args: A = {}) => ({
|
||||||
|
type: "object" as const,
|
||||||
|
properties,
|
||||||
|
...args,
|
||||||
|
}),
|
||||||
|
boolean: (args = {}) => ({ type: "boolean" as const, ...args }),
|
||||||
|
number: (args = {}) => ({ type: "number" as const, ...args }),
|
||||||
|
integer: (args = {}) => ({ type: "integer" as const, ...args }),
|
||||||
|
type: <S extends string>(type: S, args = {}) => ({ type, ...args }),
|
||||||
|
ref: <S extends string>(ref: S, args = {}) => ({ $ref: ref, ...args }),
|
||||||
|
};
|
@ -2,6 +2,7 @@ import { createSelector } from "@reduxjs/toolkit";
|
|||||||
import Updux, { createPayloadAction } from "updux";
|
import Updux, { createPayloadAction } from "updux";
|
||||||
import * as R from "remeda";
|
import * as R from "remeda";
|
||||||
import memoize from "memoize-one";
|
import memoize from "memoize-one";
|
||||||
|
import Ajv from "ajv";
|
||||||
|
|
||||||
import identification from "./ship/identification";
|
import identification from "./ship/identification";
|
||||||
import ftl, { calcFtlReqs } from "./ship/propulsion/ftl";
|
import ftl, { calcFtlReqs } from "./ship/propulsion/ftl";
|
||||||
@ -18,6 +19,7 @@ import { fireconsDux } from "./ship/weaponry/firecons";
|
|||||||
import { adfcDux } from "./ship/weaponry/adfc";
|
import { adfcDux } from "./ship/weaponry/adfc";
|
||||||
import { weaponsDux } from "./ship/weaponry/weapons";
|
import { weaponsDux } from "./ship/weaponry/weapons";
|
||||||
import { weaponryDux } from "./ship/weaponry";
|
import { weaponryDux } from "./ship/weaponry";
|
||||||
|
import schema from "./ship/schema";
|
||||||
|
|
||||||
if (typeof process !== "undefined") {
|
if (typeof process !== "undefined") {
|
||||||
process.env.UPDEEP_MODE = "dangerously_never_freeze";
|
process.env.UPDEEP_MODE = "dangerously_never_freeze";
|
||||||
@ -64,6 +66,31 @@ const shipDux = new Updux({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
shipDux.addEffect((api) => {
|
||||||
|
const ajv = new Ajv();
|
||||||
|
|
||||||
|
const validate = ajv.compile(schema);
|
||||||
|
|
||||||
|
return (next) => (action) => {
|
||||||
|
next(action);
|
||||||
|
|
||||||
|
if (!validate(api.getState())) {
|
||||||
|
console.error(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
errors: validate.errors,
|
||||||
|
state: api.getState(),
|
||||||
|
action,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
throw new Error("validation failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
shipDux.addMutation(restore, (state) => () => state);
|
shipDux.addMutation(restore, (state) => () => state);
|
||||||
shipDux.addMutation(importShip, (state) => () => state);
|
shipDux.addMutation(importShip, (state) => () => state);
|
||||||
|
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import Updux, { createAction, withPayload } from "updux";
|
import Updux, { createAction, withPayload } from "updux";
|
||||||
import u from "@yanick/updeep-remeda";
|
import u from "@yanick/updeep-remeda";
|
||||||
import { carrierDux } from "./carrier";
|
import { carrierDux } from "./carrier";
|
||||||
|
import type { FromSchema } from "json-schema-to-ts";
|
||||||
|
import * as j from "json-schema-shorthand";
|
||||||
|
|
||||||
const initialState = {
|
import {
|
||||||
shipType: "",
|
identificationSchema,
|
||||||
shipClass: "",
|
type Identification,
|
||||||
isCarrier: false,
|
} from "./identification/schema.js";
|
||||||
reqs: {
|
|
||||||
mass: 10,
|
const initialState: Identification = identificationSchema.default;
|
||||||
cost: 0,
|
|
||||||
usedMass: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const setShipClass = createAction("setShipClass", withPayload<string>());
|
const setShipClass = createAction("setShipClass", withPayload<string>());
|
||||||
const updateIdentification = createAction("updateIdentification");
|
const updateIdentification = createAction("updateIdentification");
|
||||||
|
33
src/lib/store/ship/identification/schema.ts
Normal file
33
src/lib/store/ship/identification/schema.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import type { FromSchema } from "json-schema-to-ts";
|
||||||
|
import * as j from "json-schema-shorthand";
|
||||||
|
|
||||||
|
import { reqsSchema } from "../reqs";
|
||||||
|
|
||||||
|
export const identificationSchema = j.object(
|
||||||
|
{
|
||||||
|
shipType: "string",
|
||||||
|
shipClass: "string",
|
||||||
|
isCarrier: { type: "boolean", default: false },
|
||||||
|
reqs: {
|
||||||
|
allOf: ["#/$defs/reqs", { object: { usedMass: "number" } }],
|
||||||
|
},
|
||||||
|
} as const,
|
||||||
|
{
|
||||||
|
additionalProperties: false,
|
||||||
|
$defs: {
|
||||||
|
reqs: reqsSchema,
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
shipType: "",
|
||||||
|
shipClass: "",
|
||||||
|
isCarrier: false,
|
||||||
|
reqs: {
|
||||||
|
mass: 10,
|
||||||
|
cost: 0,
|
||||||
|
usedMass: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const
|
||||||
|
);
|
||||||
|
|
||||||
|
export type Identification = FromSchema<typeof identificationSchema>;
|
11
src/lib/store/ship/reqs.ts
Normal file
11
src/lib/store/ship/reqs.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import type { FromSchema, JSONSchema } from "json-schema-to-ts";
|
||||||
|
import * as j from "json-schema-shorthand";
|
||||||
|
|
||||||
|
import jsc from "$lib/jsc";
|
||||||
|
|
||||||
|
export const reqsSchema = j.object({
|
||||||
|
cost: "integer",
|
||||||
|
mass: "integer",
|
||||||
|
} as const);
|
||||||
|
|
||||||
|
export type Reqs = FromSchema<typeof reqsSchema>;
|
28
src/lib/store/ship/schema.test.ts
Normal file
28
src/lib/store/ship/schema.test.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import schema from "./schema";
|
||||||
|
import shipDux from "../ship";
|
||||||
|
import Ajv from "ajv";
|
||||||
|
|
||||||
|
const ajv = new Ajv();
|
||||||
|
|
||||||
|
test("initial value is valid", () => {
|
||||||
|
const validate = ajv.compile(schema);
|
||||||
|
console.log(shipDux.initialState);
|
||||||
|
|
||||||
|
try {
|
||||||
|
expect(validate(shipDux.initialState)).toBeTruthy();
|
||||||
|
} catch (e) {
|
||||||
|
if (validate.errors) {
|
||||||
|
console.warn(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
state: shipDux.initialState,
|
||||||
|
error: validate.errors,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw new Error("validation failed");
|
||||||
|
}
|
||||||
|
});
|
29
src/lib/store/ship/schema.ts
Normal file
29
src/lib/store/ship/schema.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const todo = {
|
||||||
|
type: "object",
|
||||||
|
additionalProperties: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const shipSchema = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
schemaVersion: { const: "1" },
|
||||||
|
identification: { $ref: "#/$defs/identification" },
|
||||||
|
structure: { $ref: "#/$defs/todo" },
|
||||||
|
propulsion: { $ref: "#/$defs/todo" },
|
||||||
|
carrier: { $ref: "#/$defs/todo" },
|
||||||
|
weaponry: { $ref: "#/$defs/todo" },
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
$defs: {
|
||||||
|
identification: identificationSchema,
|
||||||
|
todo,
|
||||||
|
...identificationSchema.$defs,
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
import type { FromSchema } from "json-schema-to-ts";
|
||||||
|
import { identificationSchema } from "./identification/schema";
|
||||||
|
|
||||||
|
type Ship = FromSchema<typeof shipSchema>;
|
||||||
|
|
||||||
|
export default shipSchema;
|
@ -1,4 +1,3 @@
|
|||||||
// vite.config.js
|
|
||||||
import { sveltekit } from "@sveltejs/kit/vite";
|
import { sveltekit } from "@sveltejs/kit/vite";
|
||||||
import packageJson from "./package.json";
|
import packageJson from "./package.json";
|
||||||
import getVersion from "git-repo-version";
|
import getVersion from "git-repo-version";
|
||||||
|
Loading…
Reference in New Issue
Block a user