feat!: adjust cache builder for current database
Also adjusts publication ref values and blessed tradition principle ref values, which might break current database data.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
gen
|
||||
node_modules
|
||||
lib
|
||||
*.tsbuildinfo
|
||||
|
||||
# Swift
|
||||
.DS_Store
|
||||
|
||||
Generated
+11
-11
@@ -10,7 +10,7 @@
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@elyukai/utils": "^0.2.0",
|
||||
"tsondb": "^0.19.3",
|
||||
"tsondb": "^0.19.8",
|
||||
"yaml": "^2.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -50,9 +50,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@elyukai/utils": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@elyukai/utils/-/utils-0.2.0.tgz",
|
||||
"integrity": "sha512-UWt39Gb9YU8G9fy5F9oUp4D3XfPCBhLXnHbRD8oczU3itQ3iKqSRKQ7k4+8cs7b37HefgVhFkMScMfvXvbXjPQ==",
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@elyukai/utils/-/utils-0.2.1.tgz",
|
||||
"integrity": "sha512-az6I2MHjZ+QEJNcK7xTe/z7dNucBwyT9mYe3BNGl4iUHQiTc2DuMEbsAYrITLtVNTJT6yO6p48m9bzOiVQJO9w==",
|
||||
"license": "MPL-2.0"
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
@@ -290,9 +290,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@preact/signals": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@preact/signals/-/signals-2.7.0.tgz",
|
||||
"integrity": "sha512-9rQ030JhUfdBO4xlFB6Iwc/rOBi9IFXaCgu8VrFMSjAJfubGRTTxBPsgSlAF5qmWdY3C91b9kBK09mpUOMh1Rw==",
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@preact/signals/-/signals-2.7.1.tgz",
|
||||
"integrity": "sha512-mP2+wMYHqDXVKFGzjqkL6CiHj3okB8eVTTJUZBrSVGozi/XfA+zZRCEALKKZYRoSoqLyT4J6qM4lhwT9155s1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@preact/signals-core": "^1.13.0"
|
||||
@@ -4165,12 +4165,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tsondb": {
|
||||
"version": "0.19.3",
|
||||
"resolved": "https://registry.npmjs.org/tsondb/-/tsondb-0.19.3.tgz",
|
||||
"integrity": "sha512-kfdyzhoIatOUzJfYZCKlIRALPPVl/hGpOpCAmdao+s+dCCdJF1Vw39oE0A555Rm8w8xAxqByvL1qv2Cirelj5g==",
|
||||
"version": "0.19.8",
|
||||
"resolved": "https://registry.npmjs.org/tsondb/-/tsondb-0.19.8.tgz",
|
||||
"integrity": "sha512-1RG6kV+uZvoj9viXTgZqXBnwV3wcizvdqsswai4Ar3aOMczspu73UZAE3p9Xjk/XmQsO5JMoICU8AP+MiRTNqA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@elyukai/utils": "^0.2.0",
|
||||
"@elyukai/utils": "^0.2.1",
|
||||
"@preact/signals": "^2.7.0",
|
||||
"debug": "^4.4.3",
|
||||
"express": "^5.2.1",
|
||||
|
||||
+4
-4
@@ -18,10 +18,10 @@
|
||||
"main": "./lib/main.js",
|
||||
"exports": {
|
||||
".": "./lib/main.js",
|
||||
"./gen": "./gen/types.d.ts",
|
||||
"./cache/*": "./lib/cache/*.js",
|
||||
"./cache": "./lib/cache/index.js",
|
||||
"./types": "./lib/types/index.js",
|
||||
"./types/*": "./lib/types/*.js"
|
||||
"./types/*": "./lib/types/*.js",
|
||||
"./gen": "./gen/types.d.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
@@ -38,7 +38,7 @@
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@elyukai/utils": "^0.2.0",
|
||||
"tsondb": "^0.19.3",
|
||||
"tsondb": "^0.19.8",
|
||||
"yaml": "^2.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
+856
-980
File diff suppressed because it is too large
Load Diff
Vendored
+23
-28
@@ -1,30 +1,25 @@
|
||||
import type { CacheConfig } from "../cacheConfig.js"
|
||||
import type { Advantage_ID } from "../../gen/types.js"
|
||||
import type { CacheBuilder } from "./internal.ts"
|
||||
|
||||
export type AncestorBloodAdvantagesCache = {
|
||||
ids: number[]
|
||||
}
|
||||
export type AncestorBloodAdvantagesCache = Advantage_ID[]
|
||||
|
||||
export const config: CacheConfig<AncestorBloodAdvantagesCache> = {
|
||||
builder(database) {
|
||||
return {
|
||||
ids: database.advantages
|
||||
.filter(([id, advantage]) =>
|
||||
advantage.prerequisites?.some(p => {
|
||||
switch (p.prerequisite.tag) {
|
||||
case "Single":
|
||||
return p.prerequisite.single.tag === "NoOtherAncestorBloodAdvantage"
|
||||
case "Disjunction":
|
||||
return p.prerequisite.disjunction.list.some(
|
||||
d => d.tag === "NoOtherAncestorBloodAdvantage"
|
||||
)
|
||||
case "Group":
|
||||
return p.prerequisite.group.list.some(
|
||||
g => g.tag === "NoOtherAncestorBloodAdvantage"
|
||||
)
|
||||
}
|
||||
})
|
||||
)
|
||||
.map(([id]) => id),
|
||||
}
|
||||
},
|
||||
}
|
||||
export const buildAncestorBloodAdvantagesCache: CacheBuilder<
|
||||
AncestorBloodAdvantagesCache
|
||||
> = database =>
|
||||
database
|
||||
.getAllInstanceContainersOfEntity("Advantage")
|
||||
.filter(({ content }) =>
|
||||
content.prerequisites?.some(p => {
|
||||
switch (p.prerequisite.kind) {
|
||||
case "Single":
|
||||
return p.prerequisite.Single.kind === "NoOtherAncestorBloodAdvantage"
|
||||
case "Disjunction":
|
||||
return p.prerequisite.Disjunction.list.some(
|
||||
d => d.kind === "NoOtherAncestorBloodAdvantage",
|
||||
)
|
||||
case "Group":
|
||||
return p.prerequisite.Group.list.some(g => g.kind === "NoOtherAncestorBloodAdvantage")
|
||||
}
|
||||
}),
|
||||
)
|
||||
.map(({ id }) => id)
|
||||
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
import { ValidResults } from "../main.js"
|
||||
|
||||
export type CacheConfig<T, D extends unknown[] = []> = {
|
||||
builder: (data: ValidResults, ...deps: D) => T
|
||||
}
|
||||
Vendored
+69
@@ -0,0 +1,69 @@
|
||||
import type { TSONDB } from "tsondb"
|
||||
import type { TSONDBTypes } from "../main.ts"
|
||||
import {
|
||||
activatableSelectOptionsCacheBuilder,
|
||||
type ActivatableSelectOptionsCache,
|
||||
} from "./activatableSelectOptions.ts"
|
||||
import {
|
||||
buildAncestorBloodAdvantagesCache,
|
||||
type AncestorBloodAdvantagesCache,
|
||||
} from "./ancestorBloodAdvantages.ts"
|
||||
import {
|
||||
buildMagicalAndBlessedAdvantagesAndDisadvantagesCache,
|
||||
type MagicalAndBlessedAdvantagesAndDisadvantagesCache,
|
||||
} from "./magicalAndBlessedAdvantagesAndDisadvantages.ts"
|
||||
import {
|
||||
buildNewApplicationsAndUsesCache,
|
||||
type NewApplicationsAndUsesCache,
|
||||
} from "./newApplicationsAndUses.ts"
|
||||
|
||||
/**
|
||||
* Identifiers of specific entries in the database that are used for creating the cache.
|
||||
*/
|
||||
export type IdMap = {
|
||||
Advantage: Record<"Blessed" | "Spellcaster", string>
|
||||
MagicalSpecialAbility: Record<"PropertyKnowledge", string>
|
||||
KarmaSpecialAbility: Record<"AspectKnowledge", string>
|
||||
}
|
||||
|
||||
/**
|
||||
* The cache object containing all precomputed data.
|
||||
*/
|
||||
export type Cache = {
|
||||
activatableSelectOptions: ActivatableSelectOptionsCache
|
||||
sncestorBloodAdvantages: AncestorBloodAdvantagesCache
|
||||
magicalAndBlessedAdvantagesAndDisadvantages: MagicalAndBlessedAdvantagesAndDisadvantagesCache
|
||||
newApplicationsAndUses: NewApplicationsAndUsesCache
|
||||
}
|
||||
|
||||
export type {
|
||||
ActivatableSelectOptionsCache,
|
||||
AncestorBloodAdvantagesCache,
|
||||
MagicalAndBlessedAdvantagesAndDisadvantagesCache,
|
||||
NewApplicationsAndUsesCache,
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the cache by precomputing all necessary data from the database.
|
||||
* @param db The TSONDB instance containing the database.
|
||||
* @param idMap An object containing identifiers of specific entries in the database that are used for creating the cache.
|
||||
* @returns The created cache object.
|
||||
*/
|
||||
export const createCache = (db: TSONDB<TSONDBTypes>, idMap: IdMap): Cache => {
|
||||
const activatableSelectOptions = activatableSelectOptionsCacheBuilder(db, idMap)
|
||||
const sncestorBloodAdvantages = buildAncestorBloodAdvantagesCache(db, idMap)
|
||||
const magicalAndBlessedAdvantagesAndDisadvantages =
|
||||
buildMagicalAndBlessedAdvantagesAndDisadvantagesCache(db, idMap)
|
||||
const newApplicationsAndUses = buildNewApplicationsAndUsesCache(
|
||||
db,
|
||||
idMap,
|
||||
activatableSelectOptions,
|
||||
)
|
||||
|
||||
return {
|
||||
activatableSelectOptions,
|
||||
sncestorBloodAdvantages,
|
||||
magicalAndBlessedAdvantagesAndDisadvantages,
|
||||
newApplicationsAndUses,
|
||||
}
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import type { TSONDB } from "tsondb"
|
||||
import type { TSONDBTypes } from "../main.ts"
|
||||
import type { IdMap } from "./index.ts"
|
||||
|
||||
export type CacheBuilder<T = unknown, Args extends unknown[] = []> = (
|
||||
db: TSONDB<TSONDBTypes>,
|
||||
idMap: IdMap,
|
||||
...args: Args
|
||||
) => T
|
||||
+96
-127
@@ -1,41 +1,35 @@
|
||||
import { assertExhaustive } from "@elyukai/utils/typeSafety"
|
||||
import type { CacheConfig } from "../cacheConfig.js"
|
||||
import type { TSONDB } from "tsondb"
|
||||
import type {
|
||||
ActivatableIdentifier,
|
||||
Advantage_ID,
|
||||
AdvantageDisadvantagePrerequisiteGroup,
|
||||
AdvantageDisadvantagePrerequisites,
|
||||
Disadvantage_ID,
|
||||
RatedIdentifier,
|
||||
} from "../../gen/types.js"
|
||||
import type { TSONDBTypes } from "../main.js"
|
||||
import type { IdMap } from "./index.js"
|
||||
import type { CacheBuilder } from "./internal.ts"
|
||||
|
||||
const BLESSED_ID = 12
|
||||
const SPELLCASTER_ID = 47
|
||||
export type MagicalAndBlessedAdvantagesAndDisadvantagesCache = Record<
|
||||
"Advantage" | "Disadvantage",
|
||||
Record<"Magical" | "Blessed", string[]>
|
||||
>
|
||||
|
||||
export type MagicalAndBlessedAdvantagesAndDisadvantagesCache = {
|
||||
advantages: {
|
||||
magical: {
|
||||
ids: number[]
|
||||
}
|
||||
blessed: {
|
||||
ids: number[]
|
||||
}
|
||||
}
|
||||
disadvantages: {
|
||||
magical: {
|
||||
ids: number[]
|
||||
}
|
||||
blessed: {
|
||||
ids: number[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getAdvantageId = (type: "Magical" | "Blessed") => {
|
||||
const getAdvantageId = (idMap: IdMap, type: "Magical" | "Blessed") => {
|
||||
switch (type) {
|
||||
case "Magical":
|
||||
return SPELLCASTER_ID
|
||||
return idMap.Advantage.Spellcaster
|
||||
case "Blessed":
|
||||
return BLESSED_ID
|
||||
return idMap.Advantage.Blessed
|
||||
default:
|
||||
return assertExhaustive(type)
|
||||
}
|
||||
}
|
||||
|
||||
const isRatedFor = (type: "Magical" | "Blessed", ratedId: RatedIdentifier) => {
|
||||
switch (ratedId.tag) {
|
||||
switch (ratedId.kind) {
|
||||
case "Spell":
|
||||
case "Ritual":
|
||||
return type === "Magical"
|
||||
@@ -53,28 +47,29 @@ const isRatedFor = (type: "Magical" | "Blessed", ratedId: RatedIdentifier) => {
|
||||
}
|
||||
|
||||
const isPrerequisiteFor = (
|
||||
idMap: IdMap,
|
||||
type: "Magical" | "Blessed",
|
||||
prerequisite: AdvantageDisadvantagePrerequisiteGroup,
|
||||
getById: (
|
||||
id: ActivatableIdentifier,
|
||||
) => { id: number; prerequisites?: AdvantageDisadvantagePrerequisites } | undefined,
|
||||
traversedIds: number[],
|
||||
) => { id: string; content: { prerequisites?: AdvantageDisadvantagePrerequisites } } | undefined,
|
||||
traversedIds: string[],
|
||||
): boolean => {
|
||||
switch (prerequisite.tag) {
|
||||
switch (prerequisite.kind) {
|
||||
case "Activatable": {
|
||||
if (
|
||||
prerequisite.activatable.id.tag === "Advantage" &&
|
||||
prerequisite.activatable.id.advantage === getAdvantageId(type) &&
|
||||
prerequisite.activatable.active
|
||||
prerequisite.Activatable.id.kind === "Advantage" &&
|
||||
prerequisite.Activatable.id.Advantage === getAdvantageId(idMap, type) &&
|
||||
prerequisite.Activatable.active
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
const entry = getById(prerequisite.activatable.id)
|
||||
return entry !== undefined && is(type, entry, getById, traversedIds)
|
||||
const entry = getById(prerequisite.Activatable.id)
|
||||
return entry !== undefined && is(idMap, type, entry, getById, traversedIds)
|
||||
}
|
||||
case "Rated":
|
||||
return isRatedFor(type, prerequisite.rated.id)
|
||||
return isRatedFor(type, prerequisite.Rated.id)
|
||||
case "CommonSuggestedByRCP":
|
||||
case "Sex":
|
||||
case "Race":
|
||||
@@ -88,7 +83,7 @@ const isPrerequisiteFor = (
|
||||
case "MagicalTradition":
|
||||
case "RatedMinimumNumber":
|
||||
case "RatedSum":
|
||||
case "ExternalEnhancement":
|
||||
case "Enhancement":
|
||||
case "Text":
|
||||
case "NoOtherAncestorBloodAdvantage":
|
||||
case "SexualCharacteristic":
|
||||
@@ -99,32 +94,39 @@ const isPrerequisiteFor = (
|
||||
}
|
||||
|
||||
const is = (
|
||||
idMap: IdMap,
|
||||
type: "Magical" | "Blessed",
|
||||
entry: { id: number; prerequisites?: AdvantageDisadvantagePrerequisites },
|
||||
entry: { id: string; content: { prerequisites?: AdvantageDisadvantagePrerequisites } },
|
||||
getById: (
|
||||
id: ActivatableIdentifier,
|
||||
) => { id: number; prerequisites?: AdvantageDisadvantagePrerequisites } | undefined,
|
||||
traversedIds: number[],
|
||||
) => { id: string; content: { prerequisites?: AdvantageDisadvantagePrerequisites } } | undefined,
|
||||
traversedIds: string[],
|
||||
): boolean => {
|
||||
if (!entry.prerequisites || traversedIds.includes(entry.id)) {
|
||||
if (!entry.content.prerequisites || traversedIds.includes(entry.id)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const newTraversedIds = [...traversedIds, entry.id]
|
||||
|
||||
return (
|
||||
entry.prerequisites !== undefined &&
|
||||
entry.prerequisites.some(prerequisite => {
|
||||
switch (prerequisite.prerequisite.tag) {
|
||||
entry.content.prerequisites !== undefined &&
|
||||
entry.content.prerequisites.some(prerequisite => {
|
||||
switch (prerequisite.prerequisite.kind) {
|
||||
case "Single":
|
||||
return isPrerequisiteFor(type, prerequisite.prerequisite.single, getById, newTraversedIds)
|
||||
return isPrerequisiteFor(
|
||||
idMap,
|
||||
type,
|
||||
prerequisite.prerequisite.Single,
|
||||
getById,
|
||||
newTraversedIds,
|
||||
)
|
||||
case "Disjunction":
|
||||
return prerequisite.prerequisite.disjunction.list.some(p =>
|
||||
isPrerequisiteFor(type, p, getById, newTraversedIds),
|
||||
return prerequisite.prerequisite.Disjunction.list.some(p =>
|
||||
isPrerequisiteFor(idMap, type, p, getById, newTraversedIds),
|
||||
)
|
||||
case "Group":
|
||||
return prerequisite.prerequisite.group.list.some(p =>
|
||||
isPrerequisiteFor(type, p, getById, newTraversedIds),
|
||||
return prerequisite.prerequisite.Group.list.some(p =>
|
||||
isPrerequisiteFor(idMap, type, p, getById, newTraversedIds),
|
||||
)
|
||||
default:
|
||||
return assertExhaustive(prerequisite.prerequisite)
|
||||
@@ -133,84 +135,51 @@ const is = (
|
||||
)
|
||||
}
|
||||
|
||||
export const config: CacheConfig<MagicalAndBlessedAdvantagesAndDisadvantagesCache> = {
|
||||
builder(database) {
|
||||
const getActivatableById = (id: ActivatableIdentifier) => {
|
||||
// prettier-ignore
|
||||
switch (id.tag) {
|
||||
case "AdvancedCombatSpecialAbility": return database.advancedCombatSpecialAbilities.find(([entryId]) => entryId === id.advanced_combat_special_ability)?.[1]
|
||||
case "AdvancedKarmaSpecialAbility": return database.advancedKarmaSpecialAbilities.find(([entryId]) => entryId === id.advanced_karma_special_ability)?.[1]
|
||||
case "AdvancedMagicalSpecialAbility": return database.advancedMagicalSpecialAbilities.find(([entryId]) => entryId === id.advanced_magical_special_ability)?.[1]
|
||||
case "AdvancedSkillSpecialAbility": return database.advancedSkillSpecialAbilities.find(([entryId]) => entryId === id.advanced_skill_special_ability)?.[1]
|
||||
case "Advantage": return database.advantages.find(([entryId]) => entryId === id.advantage)?.[1]
|
||||
case "AncestorGlyph": return database.ancestorGlyphs.find(([entryId]) => entryId === id.ancestor_glyph)?.[1]
|
||||
case "ArcaneOrbEnchantment": return database.arcaneOrbEnchantments.find(([entryId]) => entryId === id.arcane_orb_enchantment)?.[1]
|
||||
case "AttireEnchantment": return database.attireEnchantments.find(([entryId]) => entryId === id.attire_enchantment)?.[1]
|
||||
case "BlessedTradition": return database.blessedTraditions.find(([entryId]) => entryId === id.blessed_tradition)?.[1]
|
||||
case "BowlEnchantment": return database.bowlEnchantments.find(([entryId]) => entryId === id.bowl_enchantment)?.[1]
|
||||
case "BrawlingSpecialAbility": return database.brawlingSpecialAbilities.find(([entryId]) => entryId === id.brawling_special_ability)?.[1]
|
||||
case "CauldronEnchantment": return database.cauldronEnchantments.find(([entryId]) => entryId === id.cauldron_enchantment)?.[1]
|
||||
case "CeremonialItemSpecialAbility": return database.ceremonialItemSpecialAbilities.find(([entryId]) => entryId === id.ceremonial_item_special_ability)?.[1]
|
||||
case "ChronicleEnchantment": return database.chronicleEnchantments.find(([entryId]) => entryId === id.chronicle_enchantment)?.[1]
|
||||
case "CombatSpecialAbility": return database.combatSpecialAbilities.find(([entryId]) => entryId === id.combat_special_ability)?.[1]
|
||||
case "CombatStyleSpecialAbility": return database.combatStyleSpecialAbilities.find(([entryId]) => entryId === id.combat_style_special_ability)?.[1]
|
||||
case "CommandSpecialAbility": return database.commandSpecialAbilities.find(([entryId]) => entryId === id.command_special_ability)?.[1]
|
||||
case "DaggerRitual": return database.daggerRituals.find(([entryId]) => entryId === id.dagger_ritual)?.[1]
|
||||
case "Disadvantage": return database.disadvantages.find(([entryId]) => entryId === id.disadvantage)?.[1]
|
||||
case "FamiliarSpecialAbility": return database.familiarSpecialAbilities.find(([entryId]) => entryId === id.familiar_special_ability)?.[1]
|
||||
case "FatePointSexSpecialAbility": return database.fatePointSexSpecialAbilities.find(([entryId]) => entryId === id.fate_point_sex_special_ability)?.[1]
|
||||
case "FatePointSpecialAbility": return database.fatePointSpecialAbilities.find(([entryId]) => entryId === id.fate_point_special_ability)?.[1]
|
||||
case "FoolsHatEnchantment": return database.foolsHatEnchantments.find(([entryId]) => entryId === id.fools_hat_enchantment)?.[1]
|
||||
case "GeneralSpecialAbility": return database.generalSpecialAbilities.find(([entryId]) => entryId === id.general_special_ability)?.[1]
|
||||
case "InstrumentEnchantment": return database.instrumentEnchantments.find(([entryId]) => entryId === id.instrument_enchantment)?.[1]
|
||||
case "KarmaSpecialAbility": return database.karmaSpecialAbilities.find(([entryId]) => entryId === id.karma_special_ability)?.[1]
|
||||
case "Krallenkettenzauber": return database.krallenkettenzauber.find(([entryId]) => entryId === id.krallenkettenzauber)?.[1]
|
||||
case "LiturgicalStyleSpecialAbility": return database.liturgicalStyleSpecialAbilities.find(([entryId]) => entryId === id.liturgical_style_special_ability)?.[1]
|
||||
case "LycantropicGift": return database.lycantropicGifts.find(([entryId]) => entryId === id.lycantropic_gift)?.[1]
|
||||
case "MagicalSign": return database.magicalSigns.find(([entryId]) => entryId === id.magical_sign)?.[1]
|
||||
case "MagicalSpecialAbility": return database.magicalSpecialAbilities.find(([entryId]) => entryId === id.magical_special_ability)?.[1]
|
||||
case "MagicalTradition": return database.magicalTraditions.find(([entryId]) => entryId === id.magical_tradition)?.[1]
|
||||
case "MagicStyleSpecialAbility": return database.magicStyleSpecialAbilities.find(([entryId]) => entryId === id.magic_style_special_ability)?.[1]
|
||||
case "OrbEnchantment": return database.orbEnchantments.find(([entryId]) => entryId === id.orb_enchantment)?.[1]
|
||||
case "PactGift": return database.pactGifts.find(([entryId]) => entryId === id.pact_gift)?.[1]
|
||||
case "ProtectiveWardingCircleSpecialAbility": return database.protectiveWardingCircleSpecialAbilities.find(([entryId]) => entryId === id.protective_warding_circle_special_ability)?.[1]
|
||||
case "RingEnchantment": return database.ringEnchantments.find(([entryId]) => entryId === id.ring_enchantment)?.[1]
|
||||
case "Sermon": return database.sermons.find(([entryId]) => entryId === id.sermon)?.[1]
|
||||
case "SexSpecialAbility": return database.sexSpecialAbilities.find(([entryId]) => entryId === id.sex_special_ability)?.[1]
|
||||
case "SickleRitual": return database.sickleRituals.find(([entryId]) => entryId === id.sickle_ritual)?.[1]
|
||||
case "SikaryanDrainSpecialAbility": return database.sikaryanDrainSpecialAbilities.find(([entryId]) => entryId === id.sikaryan_drain_special_ability)?.[1]
|
||||
case "SkillStyleSpecialAbility": return database.skillStyleSpecialAbilities.find(([entryId]) => entryId === id.skill_style_special_ability)?.[1]
|
||||
case "SpellSwordEnchantment": return database.spellSwordEnchantments.find(([entryId]) => entryId === id.spell_sword_enchantment)?.[1]
|
||||
case "StaffEnchantment": return database.staffEnchantments.find(([entryId]) => entryId === id.staff_enchantment)?.[1]
|
||||
case "ToyEnchantment": return database.toyEnchantments.find(([entryId]) => entryId === id.toy_enchantment)?.[1]
|
||||
case "Trinkhornzauber": return database.trinkhornzauber.find(([entryId]) => entryId === id.trinkhornzauber)?.[1]
|
||||
case "VampiricGift": return database.vampiricGifts.find(([entryId]) => entryId === id.vampiric_gift)?.[1]
|
||||
case "Vision": return database.visions.find(([entryId]) => entryId === id.vision)?.[1]
|
||||
case "WandEnchantment": return database.wandEnchantments.find(([entryId]) => entryId === id.wand_enchantment)?.[1]
|
||||
case "WeaponEnchantment": return database.weaponEnchantments.find(([entryId]) => entryId === id.weapon_enchantment)?.[1]
|
||||
default:
|
||||
return assertExhaustive(id)
|
||||
}
|
||||
}
|
||||
const entityKeyMap = {
|
||||
Advantage: null,
|
||||
Disadvantage: null,
|
||||
} as const
|
||||
|
||||
// prettier-ignore
|
||||
return {
|
||||
advantages: {
|
||||
magical: {
|
||||
ids: database.advantages.filter(([_, entry]) => is("Magical", entry, getActivatableById, [])).map(([id]) => id),
|
||||
},
|
||||
blessed: {
|
||||
ids: database.advantages.filter(([_, entry]) => is("Blessed", entry, getActivatableById, [])).map(([id]) => id),
|
||||
},
|
||||
},
|
||||
disadvantages: {
|
||||
magical: {
|
||||
ids: database.disadvantages.filter(([_, entry]) => is("Magical", entry, getActivatableById, [])).map(([id]) => id),
|
||||
},
|
||||
blessed: {
|
||||
ids: database.disadvantages.filter(([_, entry]) => is("Blessed", entry, getActivatableById, [])).map(([id]) => id),
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
type EntityKeyMap = typeof entityKeyMap
|
||||
|
||||
const typeKeyMap = {
|
||||
Magical: null,
|
||||
Blessed: null,
|
||||
} as const
|
||||
|
||||
type TypeKeyMap = typeof typeKeyMap
|
||||
|
||||
const collectIds = (
|
||||
entity: "Advantage" | "Disadvantage",
|
||||
type: "Magical" | "Blessed",
|
||||
database: TSONDB<TSONDBTypes>,
|
||||
idMap: IdMap,
|
||||
) =>
|
||||
database
|
||||
.getAllInstanceContainersOfEntity(entity)
|
||||
.filter(entry =>
|
||||
is(idMap, type, entry, database.getInstanceContainerOfEntityById.bind(database), []),
|
||||
)
|
||||
.map(({ id }) => id)
|
||||
|
||||
export const buildMagicalAndBlessedAdvantagesAndDisadvantagesCache: CacheBuilder<
|
||||
MagicalAndBlessedAdvantagesAndDisadvantagesCache
|
||||
> = (database, idMap) => {
|
||||
return Object.fromEntries(
|
||||
(Object.keys(entityKeyMap) as (keyof EntityKeyMap)[]).map(
|
||||
(
|
||||
entity,
|
||||
): [keyof EntityKeyMap, Record<keyof TypeKeyMap, (Advantage_ID | Disadvantage_ID)[]>] => [
|
||||
entity,
|
||||
Object.fromEntries(
|
||||
(Object.keys(typeKeyMap) as (keyof TypeKeyMap)[]).map(
|
||||
(type): [keyof TypeKeyMap, (Advantage_ID | Disadvantage_ID)[]] => [
|
||||
type,
|
||||
collectIds(entity, type, database, idMap),
|
||||
],
|
||||
),
|
||||
) as Record<keyof TypeKeyMap, (Advantage_ID | Disadvantage_ID)[]>,
|
||||
],
|
||||
),
|
||||
) as Record<keyof EntityKeyMap, Record<keyof TypeKeyMap, (Advantage_ID | Disadvantage_ID)[]>>
|
||||
}
|
||||
|
||||
Vendored
+72
-159
@@ -1,171 +1,84 @@
|
||||
import type { CacheConfig } from "../cacheConfig.js"
|
||||
import type { SkillApplication, SkillUse } from "../types/_Activatable.js"
|
||||
import type { ActivatableIdentifier } from "../types/_IdentifierGroup.js"
|
||||
import { ActivatableSelectOptionsCache } from "./activatableSelectOptions.js"
|
||||
import type {
|
||||
ActivatableIdentifier,
|
||||
NewSkillApplication,
|
||||
NewSkillApplicationOrUseParentIdentifier,
|
||||
Skill_ID,
|
||||
SkillUse,
|
||||
} from "../../gen/types.js"
|
||||
import type { ActivatableSelectOptionsCache } from "./activatableSelectOptions.ts"
|
||||
import type { CacheBuilder } from "./internal.ts"
|
||||
|
||||
export type NewApplication = {
|
||||
source: ActivatableIdentifier
|
||||
data: SkillApplication
|
||||
requiredSkillRating?: number
|
||||
export type ResolvedNewSkillApplication = {
|
||||
id: string
|
||||
content: Omit<NewSkillApplication, "parent"> & {
|
||||
parent: NewSkillApplicationOrUseParentIdentifier | ActivatableIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
export type Use = {
|
||||
source: ActivatableIdentifier
|
||||
data: SkillUse
|
||||
export type ResolvedSkillUse = {
|
||||
id: string
|
||||
content: Omit<SkillUse, "parent"> & {
|
||||
parent: NewSkillApplicationOrUseParentIdentifier | ActivatableIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
const groupByAffectedSkill = <
|
||||
T extends {
|
||||
content: {
|
||||
skills: Skill_ID[]
|
||||
}
|
||||
},
|
||||
>(
|
||||
entries: T[],
|
||||
prev: Record<Skill_ID, T[]> = {},
|
||||
): Record<Skill_ID, T[]> =>
|
||||
entries.reduce<Record<Skill_ID, T[]>>(
|
||||
(acc, entry) =>
|
||||
entry.content.skills.reduce(
|
||||
(acc1, skillId) => ({ ...acc1, [skillId]: [...(acc1[skillId] ?? []), entry] }),
|
||||
acc,
|
||||
),
|
||||
prev,
|
||||
)
|
||||
|
||||
const addGeneratedEntries = (
|
||||
generatedSelectOptions: ActivatableSelectOptionsCache,
|
||||
prev: NewApplicationsAndUsesCache,
|
||||
): NewApplicationsAndUsesCache =>
|
||||
Object.values(generatedSelectOptions).reduce(
|
||||
(acc, byInstance) =>
|
||||
Object.values(byInstance).reduce(
|
||||
(acc1, resolvedSelectOptions) =>
|
||||
resolvedSelectOptions.reduce(
|
||||
(acc2, selectOption) => ({
|
||||
newApplications: groupByAffectedSkill(
|
||||
selectOption.newApplications,
|
||||
acc2.newApplications,
|
||||
),
|
||||
uses: groupByAffectedSkill(selectOption.uses, acc2.uses),
|
||||
}),
|
||||
acc1,
|
||||
),
|
||||
acc,
|
||||
),
|
||||
prev,
|
||||
)
|
||||
|
||||
export type NewApplicationsAndUsesCache = {
|
||||
newApplications: Record<number, NewApplication[]>
|
||||
uses: Record<number, Use[]>
|
||||
newApplications: Record<Skill_ID, ResolvedNewSkillApplication[]>
|
||||
uses: Record<Skill_ID, ResolvedSkillUse[]>
|
||||
}
|
||||
|
||||
export const config: CacheConfig<
|
||||
export const buildNewApplicationsAndUsesCache: CacheBuilder<
|
||||
NewApplicationsAndUsesCache,
|
||||
[generatedSelectOptions: ActivatableSelectOptionsCache]
|
||||
> = {
|
||||
builder(database, generatedSelectOptions) {
|
||||
type WithApplicationsAndUses = {
|
||||
skill_applications?: SkillApplication[]
|
||||
skill_uses?: SkillUse[]
|
||||
}
|
||||
> = (database, _idMap, generatedSelectOptions) => {
|
||||
const cache: NewApplicationsAndUsesCache = {
|
||||
newApplications: groupByAffectedSkill(
|
||||
database.getAllInstanceContainersOfEntity("NewSkillApplication"),
|
||||
),
|
||||
uses: groupByAffectedSkill(database.getAllInstanceContainersOfEntity("SkillUse")),
|
||||
}
|
||||
|
||||
const cache: NewApplicationsAndUsesCache = {
|
||||
newApplications: {},
|
||||
uses: {},
|
||||
}
|
||||
|
||||
const addNewApplicationsAndUses = (
|
||||
activatable: WithApplicationsAndUses,
|
||||
activatableId: ActivatableIdentifier
|
||||
) => {
|
||||
if (activatable.skill_applications) {
|
||||
for (const newApplication of activatable.skill_applications) {
|
||||
const pair: NewApplication = { source: activatableId, data: newApplication }
|
||||
if (newApplication.skill.tag === "Single") {
|
||||
const previous = (cache.newApplications[newApplication.skill.single.id.skill] ??= [])
|
||||
previous.push(pair)
|
||||
} else {
|
||||
for (const skill of newApplication.skill.multiple.list) {
|
||||
const previous = (cache.newApplications[skill.id.skill] ??= [])
|
||||
previous.push(pair)
|
||||
}
|
||||
if (newApplication.skill.multiple.required_skill_rating !== undefined) {
|
||||
pair.requiredSkillRating = newApplication.skill.multiple.required_skill_rating
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activatable.skill_uses) {
|
||||
for (const use of activatable.skill_uses) {
|
||||
const pair: Use = { source: activatableId, data: use }
|
||||
if (use.skill.tag === "Single") {
|
||||
const previous = (cache.uses[use.skill.single.id.skill] ??= [])
|
||||
previous.push(pair)
|
||||
} else {
|
||||
for (const skill of use.skill.multiple.list) {
|
||||
const previous = (cache.uses[skill.id.skill] ??= [])
|
||||
previous.push(pair)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
const entries: [
|
||||
[id: number, data: WithApplicationsAndUses][],
|
||||
(numericId: number) => ActivatableIdentifier,
|
||||
][] = [
|
||||
[database.advancedCombatSpecialAbilities, n => ({ tag: "AdvancedCombatSpecialAbility", advanced_combat_special_ability: n })],
|
||||
[database.advancedKarmaSpecialAbilities, n => ({ tag: "AdvancedKarmaSpecialAbility", advanced_karma_special_ability: n })],
|
||||
[database.advancedMagicalSpecialAbilities, n => ({ tag: "AdvancedMagicalSpecialAbility", advanced_magical_special_ability: n })],
|
||||
[database.advancedSkillSpecialAbilities, n => ({ tag: "AdvancedSkillSpecialAbility", advanced_skill_special_ability: n })],
|
||||
[database.advantages, n => ({ tag: "Advantage", advantage: n })],
|
||||
[database.blessedTraditions, n => ({ tag: "BlessedTradition", blessed_tradition: n })],
|
||||
[database.ceremonialItemSpecialAbilities, n => ({ tag: "CeremonialItemSpecialAbility", ceremonial_item_special_ability: n })],
|
||||
[database.combatSpecialAbilities, n => ({ tag: "CombatSpecialAbility", combat_special_ability: n })],
|
||||
[database.combatStyleSpecialAbilities, n => ({ tag: "CombatStyleSpecialAbility", combat_style_special_ability: n })],
|
||||
[database.fatePointSpecialAbilities, n => ({ tag: "FatePointSpecialAbility", fate_point_special_ability: n })],
|
||||
[database.generalSpecialAbilities, n => ({ tag: "GeneralSpecialAbility", general_special_ability: n })],
|
||||
[database.liturgicalStyleSpecialAbilities, n => ({ tag: "LiturgicalStyleSpecialAbility", liturgical_style_special_ability: n })],
|
||||
[database.magicStyleSpecialAbilities, n => ({ tag: "MagicStyleSpecialAbility", magic_style_special_ability: n })],
|
||||
[database.magicalSpecialAbilities, n => ({ tag: "MagicalSpecialAbility", magical_special_ability: n })],
|
||||
[database.magicalTraditions, n => ({ tag: "MagicalTradition", magical_tradition: n })],
|
||||
[database.sexSpecialAbilities, n => ({ tag: "SexSpecialAbility", sex_special_ability: n })],
|
||||
]
|
||||
|
||||
entries.forEach(([entityEntries, createId]) => {
|
||||
entityEntries.forEach(([numericId, activatable]) => {
|
||||
addNewApplicationsAndUses(activatable, createId(numericId))
|
||||
})
|
||||
})
|
||||
|
||||
// prettier-ignore
|
||||
const generatedEntries: [
|
||||
{ [id: number]: WithApplicationsAndUses[] },
|
||||
(numericId: number) => ActivatableIdentifier,
|
||||
][] = [
|
||||
[generatedSelectOptions.advancedCombatSpecialAbilities, id => ({ tag: "AdvancedCombatSpecialAbility", advanced_combat_special_ability: id })],
|
||||
[generatedSelectOptions.advancedKarmaSpecialAbilities, id => ({ tag: "AdvancedKarmaSpecialAbility", advanced_karma_special_ability: id })],
|
||||
[generatedSelectOptions.advancedMagicalSpecialAbilities, id => ({ tag: "AdvancedMagicalSpecialAbility", advanced_magical_special_ability: id })],
|
||||
[generatedSelectOptions.advancedSkillSpecialAbilities, id => ({ tag: "AdvancedSkillSpecialAbility", advanced_skill_special_ability: id })],
|
||||
[generatedSelectOptions.advantages, id => ({ tag: "Advantage", advantage: id })],
|
||||
[generatedSelectOptions.ancestorGlyphs, id => ({ tag: "AncestorGlyph", ancestor_glyph: id })],
|
||||
[generatedSelectOptions.arcaneOrbEnchantments, id => ({ tag: "ArcaneOrbEnchantment", arcane_orb_enchantment: id })],
|
||||
[generatedSelectOptions.attireEnchantments, id => ({ tag: "AttireEnchantment", attire_enchantment: id })],
|
||||
[generatedSelectOptions.blessedTraditions, id => ({ tag: "BlessedTradition", blessed_tradition: id })],
|
||||
[generatedSelectOptions.bowlEnchantments, id => ({ tag: "BowlEnchantment", bowl_enchantment: id })],
|
||||
[generatedSelectOptions.brawlingSpecialAbilities, id => ({ tag: "BrawlingSpecialAbility", brawling_special_ability: id })],
|
||||
[generatedSelectOptions.cauldronEnchantments, id => ({ tag: "CauldronEnchantment", cauldron_enchantment: id })],
|
||||
[generatedSelectOptions.ceremonialItemSpecialAbilities, id => ({ tag: "CeremonialItemSpecialAbility", ceremonial_item_special_ability: id })],
|
||||
[generatedSelectOptions.chronicleEnchantments, id => ({ tag: "ChronicleEnchantment", chronicle_enchantment: id })],
|
||||
[generatedSelectOptions.combatSpecialAbilities, id => ({ tag: "CombatSpecialAbility", combat_special_ability: id })],
|
||||
[generatedSelectOptions.combatStyleSpecialAbilities, id => ({ tag: "CombatStyleSpecialAbility", combat_style_special_ability: id })],
|
||||
[generatedSelectOptions.commandSpecialAbilities, id => ({ tag: "CommandSpecialAbility", command_special_ability: id })],
|
||||
[generatedSelectOptions.daggerRituals, id => ({ tag: "DaggerRitual", dagger_ritual: id })],
|
||||
[generatedSelectOptions.disadvantages, id => ({ tag: "Disadvantage", disadvantage: id })],
|
||||
[generatedSelectOptions.familiarSpecialAbilities, id => ({ tag: "FamiliarSpecialAbility", familiar_special_ability: id })],
|
||||
[generatedSelectOptions.fatePointSexSpecialAbilities, id => ({ tag: "FatePointSexSpecialAbility", fate_point_sex_special_ability: id })],
|
||||
[generatedSelectOptions.fatePointSpecialAbilities, id => ({ tag: "FatePointSpecialAbility", fate_point_special_ability: id })],
|
||||
[generatedSelectOptions.foolsHatEnchantments, id => ({ tag: "FoolsHatEnchantment", fools_hat_enchantment: id })],
|
||||
[generatedSelectOptions.generalSpecialAbilities, id => ({ tag: "GeneralSpecialAbility", general_special_ability: id })],
|
||||
[generatedSelectOptions.instrumentEnchantments, id => ({ tag: "InstrumentEnchantment", instrument_enchantment: id })],
|
||||
[generatedSelectOptions.karmaSpecialAbilities, id => ({ tag: "KarmaSpecialAbility", karma_special_ability: id })],
|
||||
[generatedSelectOptions.krallenkettenzauber, id => ({ tag: "Krallenkettenzauber", krallenkettenzauber: id })],
|
||||
[generatedSelectOptions.liturgicalStyleSpecialAbilities, id => ({ tag: "LiturgicalStyleSpecialAbility", liturgical_style_special_ability: id })],
|
||||
[generatedSelectOptions.lycantropicGifts, id => ({ tag: "LycantropicGift", lycantropic_gift: id })],
|
||||
[generatedSelectOptions.magicalSpecialAbilities, id => ({ tag: "MagicalSpecialAbility", magical_special_ability: id })],
|
||||
[generatedSelectOptions.magicalTraditions, id => ({ tag: "MagicalTradition", magical_tradition: id })],
|
||||
[generatedSelectOptions.magicStyleSpecialAbilities, id => ({ tag: "MagicStyleSpecialAbility", magic_style_special_ability: id })],
|
||||
[generatedSelectOptions.orbEnchantments, id => ({ tag: "OrbEnchantment", orb_enchantment: id })],
|
||||
[generatedSelectOptions.pactGifts, id => ({ tag: "PactGift", pact_gift: id })],
|
||||
[generatedSelectOptions.protectiveWardingCircleSpecialAbilities, id => ({ tag: "ProtectiveWardingCircleSpecialAbility", protective_warding_circle_special_ability: id })],
|
||||
[generatedSelectOptions.ringEnchantments, id => ({ tag: "RingEnchantment", ring_enchantment: id })],
|
||||
[generatedSelectOptions.sermons, id => ({ tag: "Sermon", sermon: id })],
|
||||
[generatedSelectOptions.sexSpecialAbilities, id => ({ tag: "SexSpecialAbility", sex_special_ability: id })],
|
||||
[generatedSelectOptions.sickleRituals, id => ({ tag: "SickleRitual", sickle_ritual: id })],
|
||||
[generatedSelectOptions.sikaryanDrainSpecialAbilities, id => ({ tag: "SikaryanDrainSpecialAbility", sikaryan_drain_special_ability: id })],
|
||||
[generatedSelectOptions.staffEnchantments, id => ({ tag: "StaffEnchantment", staff_enchantment: id })],
|
||||
[generatedSelectOptions.skillStyleSpecialAbilities, id => ({ tag: "SkillStyleSpecialAbility", skill_style_special_ability: id })],
|
||||
[generatedSelectOptions.spellSwordEnchantments, id => ({ tag: "SpellSwordEnchantment", spell_sword_enchantment: id })],
|
||||
[generatedSelectOptions.toyEnchantments, id => ({ tag: "ToyEnchantment", toy_enchantment: id })],
|
||||
[generatedSelectOptions.trinkhornzauber, id => ({ tag: "Trinkhornzauber", trinkhornzauber: id })],
|
||||
[generatedSelectOptions.vampiricGifts, id => ({ tag: "VampiricGift", vampiric_gift: id })],
|
||||
[generatedSelectOptions.visions, id => ({ tag: "Vision", vision: id })],
|
||||
[generatedSelectOptions.wandEnchantments, id => ({ tag: "WandEnchantment", wand_enchantment: id })],
|
||||
[generatedSelectOptions.weaponEnchantments, id => ({ tag: "WeaponEnchantment", weapon_enchantment: id })],
|
||||
]
|
||||
|
||||
generatedEntries.forEach(([ids, createId]) =>
|
||||
Object.entries(ids).forEach(([stringId, selectOptions]) => {
|
||||
const id = createId(Number.parseInt(stringId))
|
||||
selectOptions.forEach(selectOption => {
|
||||
addNewApplicationsAndUses(selectOption, id)
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
return cache
|
||||
},
|
||||
return addGeneratedEntries(generatedSelectOptions, cache)
|
||||
}
|
||||
|
||||
@@ -38,20 +38,17 @@ export const PublicationRef = DB.TypeAlias(import.meta.url, {
|
||||
name: "Occurrence",
|
||||
namePlural: "Occurrences",
|
||||
secondaryEntity: Locale,
|
||||
type: DB.Object(
|
||||
{
|
||||
initial: DB.Optional({
|
||||
comment: "The initial occurrence of the entry.",
|
||||
type: DB.IncludeIdentifier(InitialOccurrence),
|
||||
}),
|
||||
revisions: DB.Optional({
|
||||
comment:
|
||||
"Revisions of the entry, resulting in either changed page references or re-addition or removal of an entry.",
|
||||
type: DB.Array(DB.IncludeIdentifier(Revision), { minItems: 1 }),
|
||||
}),
|
||||
},
|
||||
{ minProperties: 1 },
|
||||
),
|
||||
type: DB.Object({
|
||||
initial: DB.Required({
|
||||
comment: "The initial occurrence of the entry.",
|
||||
type: DB.IncludeIdentifier(InitialOccurrence),
|
||||
}),
|
||||
revisions: DB.Optional({
|
||||
comment:
|
||||
"Revisions of the entry, resulting in either changed page references or re-addition or removal of an entry.",
|
||||
type: DB.Array(DB.IncludeIdentifier(Revision), { minItems: 1 }),
|
||||
}),
|
||||
}),
|
||||
minProperties: 1,
|
||||
}),
|
||||
}),
|
||||
@@ -97,39 +94,39 @@ const InitialOccurrence = DB.TypeAlias(import.meta.url, {
|
||||
// },
|
||||
// })
|
||||
|
||||
const _PrintingOccurrence = DB.TypeAlias(import.meta.url, {
|
||||
name: "PrintingOccurrence",
|
||||
comment: "The publication’s printing where the entry has been added, changed, or removed.",
|
||||
type: () =>
|
||||
DB.Object({
|
||||
printing: DB.Required({
|
||||
comment: "The printing number.",
|
||||
type: DB.Integer({ minimum: 1 }),
|
||||
}),
|
||||
changes: DB.Required({
|
||||
comment: "The changes made in this printing.",
|
||||
type: DB.IncludeIdentifier(PrintingChanges),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
// const _PrintingOccurrence = DB.TypeAlias(import.meta.url, {
|
||||
// name: "PrintingOccurrence",
|
||||
// comment: "The publication’s printing where the entry has been added, changed, or removed.",
|
||||
// type: () =>
|
||||
// DB.Object({
|
||||
// printing: DB.Required({
|
||||
// comment: "The printing number.",
|
||||
// type: DB.Integer({ minimum: 1 }),
|
||||
// }),
|
||||
// changes: DB.Required({
|
||||
// comment: "The changes made in this printing.",
|
||||
// type: DB.IncludeIdentifier(PrintingChanges),
|
||||
// }),
|
||||
// }),
|
||||
// })
|
||||
|
||||
const PrintingChanges = DB.Enum(import.meta.url, {
|
||||
name: "PrintingChanges",
|
||||
comment:
|
||||
"A revision of the entry, resulting in either changed page references or re-addition or removal of an entry.",
|
||||
values: () => ({
|
||||
Set: DB.EnumCase({
|
||||
comment:
|
||||
"The entry has been added, re-added or changed page(s) in this printing. The page references override any previously set ones in case an entry has been moved to a different page in a later printing.",
|
||||
type: DB.Array(DB.IncludeIdentifier(PageRange), { minItems: 1 }),
|
||||
}),
|
||||
Remove: DB.EnumCase({
|
||||
comment:
|
||||
"The entry has been removed in this printing.\n\nThis can also be used if the entry hss been removed by the release of this publication (that is, the first printing), which can be useful for books that introduce major revisions of rules into the game.",
|
||||
type: null,
|
||||
}),
|
||||
}),
|
||||
})
|
||||
// const PrintingChanges = DB.Enum(import.meta.url, {
|
||||
// name: "PrintingChanges",
|
||||
// comment:
|
||||
// "A revision of the entry, resulting in either changed page references or re-addition or removal of an entry.",
|
||||
// values: () => ({
|
||||
// Set: DB.EnumCase({
|
||||
// comment:
|
||||
// "The entry has been added, re-added or changed page(s) in this printing. The page references override any previously set ones in case an entry has been moved to a different page in a later printing.",
|
||||
// type: DB.Array(DB.IncludeIdentifier(PageRange), { minItems: 1 }),
|
||||
// }),
|
||||
// Remove: DB.EnumCase({
|
||||
// comment:
|
||||
// "The entry has been removed in this printing.\n\nThis can also be used if the entry hss been removed by the release of this publication (that is, the first printing), which can be useful for books that introduce major revisions of rules into the game.",
|
||||
// type: null,
|
||||
// }),
|
||||
// }),
|
||||
// })
|
||||
|
||||
const Revision = DB.Enum(import.meta.url, {
|
||||
name: "Revision",
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
AspectIdentifier,
|
||||
AttributeIdentifier,
|
||||
BlessingIdentifier,
|
||||
GeneralIdentifier,
|
||||
SkillIdentifier,
|
||||
} from "../_Identifier.js"
|
||||
import { CombatTechniqueIdentifier } from "../_IdentifierGroup.js"
|
||||
@@ -59,7 +60,7 @@ export const BlessedTradition = DB.Entity(import.meta.url, {
|
||||
associated_principles_id: DB.Optional({
|
||||
comment:
|
||||
"The select option’s identifier of the disadvantage *Principles* that represent this tradition’s code, if any.",
|
||||
type: DB.Integer(),
|
||||
type: GeneralIdentifier(),
|
||||
}),
|
||||
prerequisites: DB.Optional({
|
||||
type: DB.IncludeIdentifier(GeneralPrerequisites),
|
||||
|
||||
+20
-5
@@ -1,19 +1,34 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"lib": ["ESNext"],
|
||||
"erasableSyntaxOnly": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "preact",
|
||||
"lib": ["esnext"],
|
||||
"module": "NodeNext",
|
||||
"noErrorTruncation": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUncheckedSideEffectImports": false,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "lib",
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"rootDir": "src",
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "ESNext",
|
||||
"useUnknownInCatchVariables": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
},
|
||||
"include": [
|
||||
"src/types/**/*",
|
||||
"src/main.ts",
|
||||
"src/test.ts",
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user