@alpaca-software/40kdc-data 1.0.10 → 1.0.11

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.
@@ -34,7 +34,7 @@ export * from "../cruncher/index.js";
34
34
  export { effectToBuffs, parseKeywordGrant } from "../cruncher/from-dsl.js";
35
35
  export type { ActivatableBuff, ActivatableGroupRef, EffectTranslation, TranslationPerspective, UnsupportedFragment, } from "../cruncher/from-dsl.js";
36
36
  export * from "../abilities-resolver/index.js";
37
- export { encodeShareToken, decodeShareToken, shareRegistryVersion, ShareRegistryIndex, SHARE_FORMAT_VERSION, SHARE_KINDS, } from "../share/index.js";
37
+ export { encodeShareToken, decodeShareToken, rosterToShareList, shareRegistryVersion, ShareRegistryIndex, SHARE_FORMAT_VERSION, SHARE_KINDS, } from "../share/index.js";
38
38
  export type { DecodeResult, ShareBattleSize, ShareList, ShareLoadoutEntry, ShareUnit, ShareKind, ShareRegistry, } from "../share/index.js";
39
39
  export { resolveRosterUnit, resolveRosterWargear, resolveAttachedLeader, resolveAttachmentPartners, primaryDetachment, primaryDetachmentId, checkRosterLegality, checkRoster, validateRosterCore, } from "./roster-resolve.js";
40
40
  export type { UnitLegality, RosterLegality, RosterViolation, RosterViolationCode, NormRoster, } from "./roster-resolve.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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"}
@@ -37,7 +37,7 @@ export { effectToBuffs, parseKeywordGrant } from "../cruncher/from-dsl.js";
37
37
  // The eligible-abilities resolver (also reachable as Dataset.eligibleAbilities).
38
38
  export * from "../abilities-resolver/index.js";
39
39
  // Compact, URL-safe list sharing (registry-indexed `share-v1` tokens).
40
- export { encodeShareToken, decodeShareToken, shareRegistryVersion, ShareRegistryIndex, SHARE_FORMAT_VERSION, SHARE_KINDS, } from "../share/index.js";
40
+ export { encodeShareToken, decodeShareToken, rosterToShareList, shareRegistryVersion, ShareRegistryIndex, SHARE_FORMAT_VERSION, SHARE_KINDS, } from "../share/index.js";
41
41
  // Bridge helpers from the importer's RosterUnit → linked views.
42
42
  export { resolveRosterUnit, resolveRosterWargear, resolveAttachedLeader, resolveAttachmentPartners, primaryDetachment, primaryDetachmentId, checkRosterLegality, checkRoster, validateRosterCore, } from "./roster-resolve.js";
43
43
  export { pointsLimitForBattleSize, detachmentCapForBattleSize } from "./battle-sizes.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The linked, typed 40kdc dataset.\n *\n * The default {@link dataset} is built once from the data embedded in this\n * package; the top-level collections below are its accessors, re-exported for\n * the ergonomic one-liner form.\n *\n * @packageDocumentation\n *\n * @example\n * import { units } from \"@alpaca-software/40kdc-data\";\n *\n * units.find(\"Kharn\")!.abilities\n * .filter(a => a.phases.includes(\"shooting\"))\n * .map(a => a.id); // [\"berzerker-frenzy\"]\n *\n * @example\n * import { factions } from \"@alpaca-software/40kdc-data\";\n *\n * factions.find(\"World Eaters\")!.units.length;\n */\nexport { Dataset } from \"./dataset.js\";\nexport type { StackableBuff, StackableBuffGroup, ReactiveTrigger } from \"./dataset.js\";\nexport { Collection } from \"./collection.js\";\nexport type { CollectionConfig } from \"./collection.js\";\nexport {\n UnitView,\n AbilityView,\n WeaponView,\n WeaponKeywordView,\n FactionView,\n} from \"./entities.js\";\nexport { normalizeName } from \"./normalize.js\";\nexport { emptyRawData } from \"./types.js\";\nexport type { RawData } from \"./types.js\";\n\n// Wargear-loadout maths: base/maximal loadout, per-weapon bounds, validation.\nexport {\n optionCap,\n baseLoadout,\n maximalLoadout,\n weaponBounds,\n clampWeaponCount,\n validateLoadout,\n groupLoadout,\n} from \"./loadout.js\";\nexport type {\n Loadout,\n WeaponBound,\n Violation,\n LoadoutModel,\n LoadoutGroup,\n LoadoutGroupWeapon,\n} from \"./loadout.js\";\n\n// Unit point-cost maths: ordinal-aware tier selection over `points` bands.\nexport { baseUnitPoints, pointsTierMissing } from \"./pricing.js\";\n\n// The cruncher surface — buff types + the engine — re-exported from the data\n// package so downstream callers can import their whole 40kdc API from\n// `@alpaca-software/40kdc-data` without reaching into subpaths.\nexport * from \"../cruncher/index.js\";\n\n// The DSL→Buff translator that powers AbilityView.getBuffs / describeBuffs.\nexport { effectToBuffs, parseKeywordGrant } from \"../cruncher/from-dsl.js\";\nexport type {\n ActivatableBuff,\n ActivatableGroupRef,\n EffectTranslation,\n TranslationPerspective,\n UnsupportedFragment,\n} from \"../cruncher/from-dsl.js\";\n\n// The eligible-abilities resolver (also reachable as Dataset.eligibleAbilities).\nexport * from \"../abilities-resolver/index.js\";\n\n// Compact, URL-safe list sharing (registry-indexed `share-v1` tokens).\nexport {\n encodeShareToken,\n decodeShareToken,\n shareRegistryVersion,\n ShareRegistryIndex,\n SHARE_FORMAT_VERSION,\n SHARE_KINDS,\n} from \"../share/index.js\";\nexport type {\n DecodeResult,\n ShareBattleSize,\n ShareList,\n ShareLoadoutEntry,\n ShareUnit,\n ShareKind,\n ShareRegistry,\n} from \"../share/index.js\";\n\n// Bridge helpers from the importer's RosterUnit → linked views.\nexport {\n resolveRosterUnit,\n resolveRosterWargear,\n resolveAttachedLeader,\n resolveAttachmentPartners,\n primaryDetachment,\n primaryDetachmentId,\n checkRosterLegality,\n checkRoster,\n validateRosterCore,\n} from \"./roster-resolve.js\";\nexport type {\n UnitLegality,\n RosterLegality,\n RosterViolation,\n RosterViolationCode,\n NormRoster,\n} from \"./roster-resolve.js\";\nexport { pointsLimitForBattleSize, detachmentCapForBattleSize } from \"./battle-sizes.js\";\nexport { candidateAffordability } from \"./affordability.js\";\nexport type { AffordabilitySpec, AffordabilityUnit, CandidateCost } from \"./affordability.js\";\n\nimport { Dataset } from \"./dataset.js\";\n\n/** The dataset built from this package's embedded data. */\nexport const dataset = Dataset.embedded();\n\n/** All units, linked to their faction, weapons, and abilities. */\nexport const units = dataset.units;\n/** Named target archetypes referencing real units (faction_id + unit_id). */\nexport const targetProfiles = dataset.targetProfiles;\n/** All weapons, linked to the units that carry them. */\nexport const weapons = dataset.weapons;\n/** Catalog of weapon keywords (Lethal Hits, Sustained Hits N, Anti-X N+, ...). */\nexport const weaponKeywords = dataset.weaponKeywords;\n/** Catalog of universal unit abilities (Deep Strike, Scouts X\", Feel No Pain X+, ...). */\nexport const unitKeywords = dataset.unitKeywords;\n/** All factions, linked to their units, abilities, and weapons. */\nexport const factions = dataset.factions;\n/** All abilities, linked to their phases and the units that have them. */\nexport const abilities = dataset.abilities;\n/** All detachments. */\nexport const detachments = dataset.detachments;\n/** All allied-detachment / 'soup' rules. */\nexport const alliedRules = dataset.alliedRules;\n/** All enhancements. */\nexport const enhancements = dataset.enhancements;\n/** All stratagems. */\nexport const stratagems = dataset.stratagems;\n/** All wargear options. */\nexport const wargearOptions = dataset.wargearOptions;\n/** All non-weapon wargear items (icons, attachments). */\nexport const wargear = dataset.wargear;\n/** All missions. */\nexport const missions = dataset.missions;\n/** All mission matchups. */\nexport const missionMatchups = dataset.missionMatchups;\n/** All secondary mission cards. */\nexport const missionCards = dataset.missionCards;\n/** All deployment patterns. */\nexport const deploymentPatterns = dataset.deploymentPatterns;\n/** All force dispositions. */\nexport const forceDispositions = dataset.forceDispositions;\n/** Reusable terrain catalog: standard areas and scenery features. */\nexport const terrainTemplates = dataset.terrainTemplates;\n/** All terrain layouts. */\nexport const terrainLayouts = dataset.terrainLayouts;\n/** Reusable model collision hulls (polygon footprints) referenced by id. */\nexport const hullShapes = dataset.hullShapes;\n/** All resource pools. */\nexport const resourcePools = dataset.resourcePools;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The linked, typed 40kdc dataset.\n *\n * The default {@link dataset} is built once from the data embedded in this\n * package; the top-level collections below are its accessors, re-exported for\n * the ergonomic one-liner form.\n *\n * @packageDocumentation\n *\n * @example\n * import { units } from \"@alpaca-software/40kdc-data\";\n *\n * units.find(\"Kharn\")!.abilities\n * .filter(a => a.phases.includes(\"shooting\"))\n * .map(a => a.id); // [\"berzerker-frenzy\"]\n *\n * @example\n * import { factions } from \"@alpaca-software/40kdc-data\";\n *\n * factions.find(\"World Eaters\")!.units.length;\n */\nexport { Dataset } from \"./dataset.js\";\nexport type { StackableBuff, StackableBuffGroup, ReactiveTrigger } from \"./dataset.js\";\nexport { Collection } from \"./collection.js\";\nexport type { CollectionConfig } from \"./collection.js\";\nexport {\n UnitView,\n AbilityView,\n WeaponView,\n WeaponKeywordView,\n FactionView,\n} from \"./entities.js\";\nexport { normalizeName } from \"./normalize.js\";\nexport { emptyRawData } from \"./types.js\";\nexport type { RawData } from \"./types.js\";\n\n// Wargear-loadout maths: base/maximal loadout, per-weapon bounds, validation.\nexport {\n optionCap,\n baseLoadout,\n maximalLoadout,\n weaponBounds,\n clampWeaponCount,\n validateLoadout,\n groupLoadout,\n} from \"./loadout.js\";\nexport type {\n Loadout,\n WeaponBound,\n Violation,\n LoadoutModel,\n LoadoutGroup,\n LoadoutGroupWeapon,\n} from \"./loadout.js\";\n\n// Unit point-cost maths: ordinal-aware tier selection over `points` bands.\nexport { baseUnitPoints, pointsTierMissing } from \"./pricing.js\";\n\n// The cruncher surface — buff types + the engine — re-exported from the data\n// package so downstream callers can import their whole 40kdc API from\n// `@alpaca-software/40kdc-data` without reaching into subpaths.\nexport * from \"../cruncher/index.js\";\n\n// The DSL→Buff translator that powers AbilityView.getBuffs / describeBuffs.\nexport { effectToBuffs, parseKeywordGrant } from \"../cruncher/from-dsl.js\";\nexport type {\n ActivatableBuff,\n ActivatableGroupRef,\n EffectTranslation,\n TranslationPerspective,\n UnsupportedFragment,\n} from \"../cruncher/from-dsl.js\";\n\n// The eligible-abilities resolver (also reachable as Dataset.eligibleAbilities).\nexport * from \"../abilities-resolver/index.js\";\n\n// Compact, URL-safe list sharing (registry-indexed `share-v1` tokens).\nexport {\n encodeShareToken,\n decodeShareToken,\n rosterToShareList,\n shareRegistryVersion,\n ShareRegistryIndex,\n SHARE_FORMAT_VERSION,\n SHARE_KINDS,\n} from \"../share/index.js\";\nexport type {\n DecodeResult,\n ShareBattleSize,\n ShareList,\n ShareLoadoutEntry,\n ShareUnit,\n ShareKind,\n ShareRegistry,\n} from \"../share/index.js\";\n\n// Bridge helpers from the importer's RosterUnit → linked views.\nexport {\n resolveRosterUnit,\n resolveRosterWargear,\n resolveAttachedLeader,\n resolveAttachmentPartners,\n primaryDetachment,\n primaryDetachmentId,\n checkRosterLegality,\n checkRoster,\n validateRosterCore,\n} from \"./roster-resolve.js\";\nexport type {\n UnitLegality,\n RosterLegality,\n RosterViolation,\n RosterViolationCode,\n NormRoster,\n} from \"./roster-resolve.js\";\nexport { pointsLimitForBattleSize, detachmentCapForBattleSize } from \"./battle-sizes.js\";\nexport { candidateAffordability } from \"./affordability.js\";\nexport type { AffordabilitySpec, AffordabilityUnit, CandidateCost } from \"./affordability.js\";\n\nimport { Dataset } from \"./dataset.js\";\n\n/** The dataset built from this package's embedded data. */\nexport const dataset = Dataset.embedded();\n\n/** All units, linked to their faction, weapons, and abilities. */\nexport const units = dataset.units;\n/** Named target archetypes referencing real units (faction_id + unit_id). */\nexport const targetProfiles = dataset.targetProfiles;\n/** All weapons, linked to the units that carry them. */\nexport const weapons = dataset.weapons;\n/** Catalog of weapon keywords (Lethal Hits, Sustained Hits N, Anti-X N+, ...). */\nexport const weaponKeywords = dataset.weaponKeywords;\n/** Catalog of universal unit abilities (Deep Strike, Scouts X\", Feel No Pain X+, ...). */\nexport const unitKeywords = dataset.unitKeywords;\n/** All factions, linked to their units, abilities, and weapons. */\nexport const factions = dataset.factions;\n/** All abilities, linked to their phases and the units that have them. */\nexport const abilities = dataset.abilities;\n/** All detachments. */\nexport const detachments = dataset.detachments;\n/** All allied-detachment / 'soup' rules. */\nexport const alliedRules = dataset.alliedRules;\n/** All enhancements. */\nexport const enhancements = dataset.enhancements;\n/** All stratagems. */\nexport const stratagems = dataset.stratagems;\n/** All wargear options. */\nexport const wargearOptions = dataset.wargearOptions;\n/** All non-weapon wargear items (icons, attachments). */\nexport const wargear = dataset.wargear;\n/** All missions. */\nexport const missions = dataset.missions;\n/** All mission matchups. */\nexport const missionMatchups = dataset.missionMatchups;\n/** All secondary mission cards. */\nexport const missionCards = dataset.missionCards;\n/** All deployment patterns. */\nexport const deploymentPatterns = dataset.deploymentPatterns;\n/** All force dispositions. */\nexport const forceDispositions = dataset.forceDispositions;\n/** Reusable terrain catalog: standard areas and scenery features. */\nexport const terrainTemplates = dataset.terrainTemplates;\n/** All terrain layouts. */\nexport const terrainLayouts = dataset.terrainLayouts;\n/** Reusable model collision hulls (polygon footprints) referenced by id. */\nexport const hullShapes = dataset.hullShapes;\n/** All resource pools. */\nexport const resourcePools = dataset.resourcePools;\n"]}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Bridge an imported {@link Roster} to a {@link ShareList} for share-token
3
+ * encoding.
4
+ *
5
+ * `tryImportRoster` yields a lossless {@link Roster} whose refs may be
6
+ * unresolved (`id === null`) and whose resolved ids may still predate the
7
+ * embedded share registry. {@link encodeShareList}, by contrast, throws on any
8
+ * id it can't index. {@link rosterToShareList} is the best-effort adapter
9
+ * between them: it emits a {@link ShareList} carrying only resolved,
10
+ * registry-known ids, dropping anything the token can't represent.
11
+ *
12
+ * It never throws. Callers decide what a partial mapping means: compare
13
+ * `result.units.length` to `roster.units.length` to detect dropped units, then
14
+ * encode inside a try/catch (a resolved id absent from the registry still
15
+ * throws at encode time) — a list earns a share link only when it maps and
16
+ * encodes in full.
17
+ */
18
+ import type { Roster } from "../import/types.js";
19
+ import type { ShareList } from "./codec.js";
20
+ import type { ShareRegistryIndex } from "./registry.js";
21
+ /**
22
+ * Convert a {@link Roster} to a {@link ShareList}, keeping only the ids the
23
+ * given registry knows. Units whose datasheet is unresolved or unknown to the
24
+ * registry are dropped; `attachedToOrdinal` indexes into the *emitted* units.
25
+ */
26
+ export declare function rosterToShareList(roster: Roster, registry: ShareRegistryIndex): ShareList;
27
+ //# sourceMappingURL=from-roster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-roster.d.ts","sourceRoot":"","sources":["../../src/share/from-roster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,YAAY,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAOxD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,SAAS,CAoDzF"}
@@ -0,0 +1,58 @@
1
+ /** A bodyguard match key: prefer the resolved id, fall back to the raw name. */
2
+ function unitKey(u) {
3
+ return u.ref.id ?? u.ref.raw_name;
4
+ }
5
+ /**
6
+ * Convert a {@link Roster} to a {@link ShareList}, keeping only the ids the
7
+ * given registry knows. Units whose datasheet is unresolved or unknown to the
8
+ * registry are dropped; `attachedToOrdinal` indexes into the *emitted* units.
9
+ */
10
+ export function rosterToShareList(roster, registry) {
11
+ const known = (kind, id) => id !== null && registry.index(kind, id) !== undefined;
12
+ // The units that survive into the token, in roster order. Everything below
13
+ // indexes against this list — never `roster.units` — so a dropped unit can't
14
+ // shift a leader's `attachedToOrdinal`.
15
+ const emitted = roster.units.filter((u) => known("unit", u.ref.id));
16
+ const ordinalByKey = new Map();
17
+ emitted.forEach((u, i) => {
18
+ const k = unitKey(u);
19
+ if (!ordinalByKey.has(k))
20
+ ordinalByKey.set(k, i);
21
+ });
22
+ const units = emitted.map((u) => {
23
+ const loadout = u.wargear
24
+ .filter((w) => known("wargear", w.ref.id))
25
+ .map((w) => [w.ref.id, w.count]);
26
+ const la = u.leader_attachment;
27
+ const attachedToOrdinal = la
28
+ ? (ordinalByKey.get(la.bodyguard_ref.id ?? la.bodyguard_ref.raw_name) ?? null)
29
+ : null;
30
+ return {
31
+ datasheetId: u.ref.id,
32
+ modelCount: u.model_count,
33
+ isWarlord: u.is_warlord,
34
+ enhancementId: known("enhancement", u.enhancement?.id ?? null)
35
+ ? u.enhancement?.id
36
+ : null,
37
+ // The importer doesn't track allied sourcing or detachment-keyword grants.
38
+ allyFactionId: null,
39
+ allyRuleId: null,
40
+ attachedToOrdinal,
41
+ grants: [],
42
+ loadout,
43
+ };
44
+ });
45
+ return {
46
+ name: roster.name,
47
+ factionId: known("faction", roster.faction_id) ? roster.faction_id : null,
48
+ detachmentIds: roster.detachments
49
+ .map((d) => d.ref.id)
50
+ .filter((id) => known("detachment", id)),
51
+ // The codec defaults an absent battle size to strike-force; ATC lists are
52
+ // strike-force, so a null import (the source didn't encode one) maps there.
53
+ battleSize: roster.battle_size ?? "strike-force",
54
+ disposition: known("disposition", roster.force_disposition) ? roster.force_disposition : null,
55
+ units,
56
+ };
57
+ }
58
+ //# sourceMappingURL=from-roster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-roster.js","sourceRoot":"","sources":["../../src/share/from-roster.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bridge an imported {@link Roster} to a {@link ShareList} for share-token\n * encoding.\n *\n * `tryImportRoster` yields a lossless {@link Roster} whose refs may be\n * unresolved (`id === null`) and whose resolved ids may still predate the\n * embedded share registry. {@link encodeShareList}, by contrast, throws on any\n * id it can't index. {@link rosterToShareList} is the best-effort adapter\n * between them: it emits a {@link ShareList} carrying only resolved,\n * registry-known ids, dropping anything the token can't represent.\n *\n * It never throws. Callers decide what a partial mapping means: compare\n * `result.units.length` to `roster.units.length` to detect dropped units, then\n * encode inside a try/catch (a resolved id absent from the registry still\n * throws at encode time) — a list earns a share link only when it maps and\n * encodes in full.\n */\nimport type { Roster, RosterUnit } from \"../import/types.js\";\nimport type { ShareList, ShareLoadoutEntry, ShareUnit } from \"./codec.js\";\nimport type { ShareRegistryIndex } from \"./registry.js\";\n\n/** A bodyguard match key: prefer the resolved id, fall back to the raw name. */\nfunction unitKey(u: RosterUnit): string {\n return u.ref.id ?? u.ref.raw_name;\n}\n\n/**\n * Convert a {@link Roster} to a {@link ShareList}, keeping only the ids the\n * given registry knows. Units whose datasheet is unresolved or unknown to the\n * registry are dropped; `attachedToOrdinal` indexes into the *emitted* units.\n */\nexport function rosterToShareList(roster: Roster, registry: ShareRegistryIndex): ShareList {\n const known = (kind: Parameters<ShareRegistryIndex[\"index\"]>[0], id: string | null): boolean =>\n id !== null && registry.index(kind, id) !== undefined;\n\n // The units that survive into the token, in roster order. Everything below\n // indexes against this list — never `roster.units` — so a dropped unit can't\n // shift a leader's `attachedToOrdinal`.\n const emitted = roster.units.filter((u) => known(\"unit\", u.ref.id));\n const ordinalByKey = new Map<string, number>();\n emitted.forEach((u, i) => {\n const k = unitKey(u);\n if (!ordinalByKey.has(k)) ordinalByKey.set(k, i);\n });\n\n const units: ShareUnit[] = emitted.map((u) => {\n const loadout: ShareLoadoutEntry[] = u.wargear\n .filter((w) => known(\"wargear\", w.ref.id))\n .map((w) => [w.ref.id as string, w.count]);\n\n const la = u.leader_attachment;\n const attachedToOrdinal = la\n ? (ordinalByKey.get(la.bodyguard_ref.id ?? la.bodyguard_ref.raw_name) ?? null)\n : null;\n\n return {\n datasheetId: u.ref.id as string,\n modelCount: u.model_count,\n isWarlord: u.is_warlord,\n enhancementId: known(\"enhancement\", u.enhancement?.id ?? null)\n ? (u.enhancement?.id as string)\n : null,\n // The importer doesn't track allied sourcing or detachment-keyword grants.\n allyFactionId: null,\n allyRuleId: null,\n attachedToOrdinal,\n grants: [],\n loadout,\n };\n });\n\n return {\n name: roster.name,\n factionId: known(\"faction\", roster.faction_id) ? roster.faction_id : null,\n detachmentIds: roster.detachments\n .map((d) => d.ref.id)\n .filter((id): id is string => known(\"detachment\", id)),\n // The codec defaults an absent battle size to strike-force; ATC lists are\n // strike-force, so a null import (the source didn't encode one) maps there.\n battleSize: roster.battle_size ?? \"strike-force\",\n disposition: known(\"disposition\", roster.force_disposition) ? roster.force_disposition : null,\n units,\n };\n}\n"]}
@@ -16,6 +16,7 @@
16
16
  * @packageDocumentation
17
17
  */
18
18
  import { type DecodeResult, type ShareList } from "./codec.js";
19
+ import type { Roster } from "../import/types.js";
19
20
  export { SHARE_FORMAT_VERSION } from "./codec.js";
20
21
  export type { DecodeResult, ShareBattleSize, ShareList, ShareLoadoutEntry, ShareUnit, } from "./codec.js";
21
22
  export { SHARE_KINDS } from "./registry.js";
@@ -27,4 +28,11 @@ export declare const shareRegistryVersion: number;
27
28
  export declare function encodeShareToken(list: ShareList): string;
28
29
  /** Decode a `share-v1` token using the embedded registry. */
29
30
  export declare function decodeShareToken(token: string): DecodeResult;
31
+ /**
32
+ * Adapt an imported {@link Roster} to a {@link ShareList} against the embedded
33
+ * registry, keeping only resolved, registry-known ids. Pair with
34
+ * {@link encodeShareToken} (inside a try/catch) to turn a parsed list into a
35
+ * share link; see {@link rosterToShareListImpl} for the partial-mapping contract.
36
+ */
37
+ export declare function rosterToShareList(roster: Roster): ShareList;
30
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/share/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAoC,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAIjG,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAKnD,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,EAAE,MAA+B,CAAC;AAEnE,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAExD;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAE5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/share/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAoC,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAIjG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAKnD,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,EAAE,MAA+B,CAAC;AAEnE,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAExD;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAE3D"}
@@ -16,6 +16,7 @@
16
16
  * @packageDocumentation
17
17
  */
18
18
  import { decodeShareList, encodeShareList } from "./codec.js";
19
+ import { rosterToShareList as rosterToShareListImpl } from "./from-roster.js";
19
20
  import { SHARE_REGISTRY } from "./registry.generated.js";
20
21
  import { ShareRegistryIndex } from "./registry.js";
21
22
  export { SHARE_FORMAT_VERSION } from "./codec.js";
@@ -33,4 +34,13 @@ export function encodeShareToken(list) {
33
34
  export function decodeShareToken(token) {
34
35
  return decodeShareList(token, embeddedIndex);
35
36
  }
37
+ /**
38
+ * Adapt an imported {@link Roster} to a {@link ShareList} against the embedded
39
+ * registry, keeping only resolved, registry-known ids. Pair with
40
+ * {@link encodeShareToken} (inside a try/catch) to turn a parsed list into a
41
+ * share link; see {@link rosterToShareListImpl} for the partial-mapping contract.
42
+ */
43
+ export function rosterToShareList(roster) {
44
+ return rosterToShareListImpl(roster, embeddedIndex);
45
+ }
36
46
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/share/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAqC,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQlD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,oEAAoE;AACpE,MAAM,aAAa,GAAG,IAAI,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAE7D,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAW,cAAc,CAAC,OAAO,CAAC;AAEnE,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAAe;IAC9C,OAAO,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["/**\n * Compact, URL-safe list sharing for the 40kdc list builder.\n *\n * {@link encodeShareToken} packs a {@link ShareList} into a `share-v1` token\n * (registry-indexed varints, base64url); {@link decodeShareToken} reverses it\n * against the embedded {@link SHARE_REGISTRY}. The wire format and registry are\n * documented in `docs/share-token.md` so other tools can interoperate.\n *\n * @example\n * import { encodeShareToken, decodeShareToken } from \"@alpaca-software/40kdc-data\";\n *\n * const token = encodeShareToken(myList); // → \"AQ...\" (URL-safe)\n * const result = decodeShareToken(token);\n * if (result.ok) useList(result.list);\n *\n * @packageDocumentation\n */\nimport { decodeShareList, encodeShareList, type DecodeResult, type ShareList } from \"./codec.js\";\nimport { SHARE_REGISTRY } from \"./registry.generated.js\";\nimport { ShareRegistryIndex } from \"./registry.js\";\n\nexport { SHARE_FORMAT_VERSION } from \"./codec.js\";\nexport type {\n DecodeResult,\n ShareBattleSize,\n ShareList,\n ShareLoadoutEntry,\n ShareUnit,\n} from \"./codec.js\";\nexport { SHARE_KINDS } from \"./registry.js\";\nexport type { ShareKind, ShareRegistry } from \"./registry.js\";\nexport { ShareRegistryIndex } from \"./registry.js\";\n\n/** The id index built once from the package's embedded registry. */\nconst embeddedIndex = new ShareRegistryIndex(SHARE_REGISTRY);\n\n/** Registry version this package embeds (stamped into every token it writes). */\nexport const shareRegistryVersion: number = SHARE_REGISTRY.version;\n\n/** Encode a list into a URL-safe `share-v1` token using the embedded registry. */\nexport function encodeShareToken(list: ShareList): string {\n return encodeShareList(list, embeddedIndex);\n}\n\n/** Decode a `share-v1` token using the embedded registry. */\nexport function decodeShareToken(token: string): DecodeResult {\n return decodeShareList(token, embeddedIndex);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/share/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAqC,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQlD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,oEAAoE;AACpE,MAAM,aAAa,GAAG,IAAI,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAE7D,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAW,cAAc,CAAC,OAAO,CAAC;AAEnE,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAAe;IAC9C,OAAO,eAAe,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAO,qBAAqB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACtD,CAAC","sourcesContent":["/**\n * Compact, URL-safe list sharing for the 40kdc list builder.\n *\n * {@link encodeShareToken} packs a {@link ShareList} into a `share-v1` token\n * (registry-indexed varints, base64url); {@link decodeShareToken} reverses it\n * against the embedded {@link SHARE_REGISTRY}. The wire format and registry are\n * documented in `docs/share-token.md` so other tools can interoperate.\n *\n * @example\n * import { encodeShareToken, decodeShareToken } from \"@alpaca-software/40kdc-data\";\n *\n * const token = encodeShareToken(myList); // → \"AQ...\" (URL-safe)\n * const result = decodeShareToken(token);\n * if (result.ok) useList(result.list);\n *\n * @packageDocumentation\n */\nimport { decodeShareList, encodeShareList, type DecodeResult, type ShareList } from \"./codec.js\";\nimport { rosterToShareList as rosterToShareListImpl } from \"./from-roster.js\";\nimport { SHARE_REGISTRY } from \"./registry.generated.js\";\nimport { ShareRegistryIndex } from \"./registry.js\";\nimport type { Roster } from \"../import/types.js\";\n\nexport { SHARE_FORMAT_VERSION } from \"./codec.js\";\nexport type {\n DecodeResult,\n ShareBattleSize,\n ShareList,\n ShareLoadoutEntry,\n ShareUnit,\n} from \"./codec.js\";\nexport { SHARE_KINDS } from \"./registry.js\";\nexport type { ShareKind, ShareRegistry } from \"./registry.js\";\nexport { ShareRegistryIndex } from \"./registry.js\";\n\n/** The id index built once from the package's embedded registry. */\nconst embeddedIndex = new ShareRegistryIndex(SHARE_REGISTRY);\n\n/** Registry version this package embeds (stamped into every token it writes). */\nexport const shareRegistryVersion: number = SHARE_REGISTRY.version;\n\n/** Encode a list into a URL-safe `share-v1` token using the embedded registry. */\nexport function encodeShareToken(list: ShareList): string {\n return encodeShareList(list, embeddedIndex);\n}\n\n/** Decode a `share-v1` token using the embedded registry. */\nexport function decodeShareToken(token: string): DecodeResult {\n return decodeShareList(token, embeddedIndex);\n}\n\n/**\n * Adapt an imported {@link Roster} to a {@link ShareList} against the embedded\n * registry, keeping only resolved, registry-known ids. Pair with\n * {@link encodeShareToken} (inside a try/catch) to turn a parsed list into a\n * share link; see {@link rosterToShareListImpl} for the partial-mapping contract.\n */\nexport function rosterToShareList(roster: Roster): ShareList {\n return rosterToShareListImpl(roster, embeddedIndex);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alpaca-software/40kdc-data",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "type": "module",
5
5
  "description": "The 40kdc Warhammer 40K dataset behind a linked, typed API — find units, follow them to their weapons, abilities, phases, and factions. Also validates data against the canonical JSON Schemas.",
6
6
  "keywords": [