Compare commits
No commits in common. "03d367c7b031aecd51d0c9e4a8b13be39f370a6a" and "2823089f06c89d9f611ef078cd8e08c8d2c11b24" have entirely different histories.
03d367c7b0
...
2823089f06
|
|
@ -1,7 +1,130 @@
|
||||||
export * from "./system/combat";
|
// Types
|
||||||
export * from "./system/deck";
|
export type {
|
||||||
export * from "./system/encounter";
|
EffectData,
|
||||||
export * from "./system/grid-inventory";
|
EffectLifecycle,
|
||||||
export * from "./system/map";
|
EnemyData,
|
||||||
export * from "./system/utils/parse-shape";
|
CardType,
|
||||||
export * from "./system/types";
|
CardCostType,
|
||||||
|
CardTargetType,
|
||||||
|
EffectTarget,
|
||||||
|
CardData,
|
||||||
|
CardEffectTrigger,
|
||||||
|
CardEffectTarget,
|
||||||
|
EncounterType,
|
||||||
|
EncounterData,
|
||||||
|
IntentData,
|
||||||
|
ItemData,
|
||||||
|
} from "./system/types";
|
||||||
|
|
||||||
|
// Deck
|
||||||
|
export type {
|
||||||
|
GameCard,
|
||||||
|
GameCardMeta,
|
||||||
|
PlayerDeck,
|
||||||
|
DeckRegions,
|
||||||
|
} from "./system/deck";
|
||||||
|
export {
|
||||||
|
generateDeckFromInventory,
|
||||||
|
createCard,
|
||||||
|
createPlayerDeck,
|
||||||
|
generateCardId,
|
||||||
|
} from "./system/deck";
|
||||||
|
|
||||||
|
// Grid Inventory
|
||||||
|
export type {
|
||||||
|
CellCoordinate,
|
||||||
|
CellKey,
|
||||||
|
GridInventory,
|
||||||
|
InventoryItem,
|
||||||
|
MutationResult,
|
||||||
|
PlacementResult,
|
||||||
|
GameItem,
|
||||||
|
GameItemMeta,
|
||||||
|
} from "./system/grid-inventory";
|
||||||
|
export {
|
||||||
|
createGridInventory,
|
||||||
|
flipItem,
|
||||||
|
getAdjacentItems,
|
||||||
|
getItemAtCell,
|
||||||
|
getOccupiedCellSet,
|
||||||
|
moveItem,
|
||||||
|
placeItem,
|
||||||
|
removeItem as removeItemFromGrid,
|
||||||
|
rotateItem,
|
||||||
|
validatePlacement,
|
||||||
|
createItemIn,
|
||||||
|
} from "./system/grid-inventory";
|
||||||
|
|
||||||
|
// Map
|
||||||
|
export { MapNodeType, MapLayerType } from "./system/map";
|
||||||
|
export type {
|
||||||
|
MapNode,
|
||||||
|
MapLayer,
|
||||||
|
PointCrawlMap,
|
||||||
|
MapGenerationConfig,
|
||||||
|
} from "./system/map";
|
||||||
|
export {
|
||||||
|
generatePointCrawlMap,
|
||||||
|
getNode,
|
||||||
|
getChildren,
|
||||||
|
getParents,
|
||||||
|
findAllPaths,
|
||||||
|
} from "./system/map";
|
||||||
|
|
||||||
|
// Progress / Run
|
||||||
|
export type { EncounterState, RunState } from "./system/encounter";
|
||||||
|
export { buildCombatState } from "./system/encounter";
|
||||||
|
|
||||||
|
// Combat
|
||||||
|
export type {
|
||||||
|
EffectTable,
|
||||||
|
CombatEntity,
|
||||||
|
PlayerEntity,
|
||||||
|
EnemyEntity,
|
||||||
|
CombatPhase,
|
||||||
|
CombatResult,
|
||||||
|
LootEntry,
|
||||||
|
CombatState,
|
||||||
|
CombatGameContext,
|
||||||
|
} from "./system/combat/types";
|
||||||
|
export {
|
||||||
|
addEffect,
|
||||||
|
addEntityEffect,
|
||||||
|
addItemEffect,
|
||||||
|
onEntityEffectUpkeep,
|
||||||
|
onEntityPostureDamage,
|
||||||
|
onPlayerItemEffectUpkeep,
|
||||||
|
onItemPlay,
|
||||||
|
onItemDiscard,
|
||||||
|
getAliveEnemies,
|
||||||
|
getEffectTargets,
|
||||||
|
getCombatEntity,
|
||||||
|
canPlayCard,
|
||||||
|
payCardCost,
|
||||||
|
} from "./system/combat/effects";
|
||||||
|
export {
|
||||||
|
prompts as combatPrompts,
|
||||||
|
promptMainAction,
|
||||||
|
} from "./system/combat/prompts";
|
||||||
|
export { createStartWith, type Triggers } from "./system/combat/triggers";
|
||||||
|
|
||||||
|
// Utils
|
||||||
|
export { parseShapeString, type ParsedShape } from "./system/utils/parse-shape";
|
||||||
|
export {
|
||||||
|
IDENTITY_TRANSFORM,
|
||||||
|
type Transform2D,
|
||||||
|
type Point2D,
|
||||||
|
getOccupiedCells,
|
||||||
|
transformPoint,
|
||||||
|
transformShape,
|
||||||
|
checkCollision,
|
||||||
|
checkBoardCollision,
|
||||||
|
checkBounds,
|
||||||
|
rotateTransform,
|
||||||
|
flipXTransform,
|
||||||
|
flipYTransform,
|
||||||
|
} from "./system/utils/shape-collision";
|
||||||
|
|
||||||
|
// Data
|
||||||
|
export type { ContentModule } from "./data";
|
||||||
|
export { default as data } from "./data";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export * from "./effects";
|
|
||||||
export * from "./factory";
|
|
||||||
export * from "./prompts";
|
|
||||||
export * from "./triggers";
|
|
||||||
export * from "./types";
|
|
||||||
|
|
@ -18,12 +18,6 @@ export type CombatEntity = {
|
||||||
isAlive: boolean;
|
isAlive: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IPlayerState {
|
|
||||||
hp: number;
|
|
||||||
maxHp: number;
|
|
||||||
itemEffects: Record<string, EffectTable>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IPlayerDeck {
|
export interface IPlayerDeck {
|
||||||
cards: Record<string, Part<{ cardData: CardData; itemId: string }>>;
|
cards: Record<string, Part<{ cardData: CardData; itemId: string }>>;
|
||||||
regions: {
|
regions: {
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,22 @@ import {
|
||||||
CombatState,
|
CombatState,
|
||||||
EffectTable,
|
EffectTable,
|
||||||
EnemyEntity,
|
EnemyEntity,
|
||||||
IPlayerDeck,
|
|
||||||
IPlayerState,
|
|
||||||
PlayerEntity,
|
PlayerEntity,
|
||||||
} from "./types";
|
} from "../combat/types";
|
||||||
|
import { generateDeckFromInventory } from "../deck";
|
||||||
|
import { GridInventory } from "../grid-inventory";
|
||||||
|
import { GameItemMeta } from "../grid-inventory/types";
|
||||||
import { EffectData, EncounterData, EnemyData, IntentData } from "../types";
|
import { EffectData, EncounterData, EnemyData, IntentData } from "../types";
|
||||||
|
import { CombatEncounterState, RunState } from "./types";
|
||||||
|
|
||||||
export function buildCombatState(
|
export function buildCombatState(
|
||||||
playerState: IPlayerState,
|
runState: RunState,
|
||||||
deck: IPlayerDeck,
|
inventory: GridInventory<GameItemMeta>,
|
||||||
encounter: EncounterData,
|
encounter: CombatEncounterState,
|
||||||
): CombatState {
|
): CombatState {
|
||||||
const player = createPlayerEntity(playerState, deck);
|
const deck = generateDeckFromInventory(inventory);
|
||||||
const enemies = createEnemyEntities(encounter);
|
const player = createPlayerEntity(runState, deck);
|
||||||
|
const enemies = createEnemyEntities(encounter.data);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enemies,
|
enemies,
|
||||||
|
|
@ -26,6 +29,12 @@ export function buildCombatState(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildCombatEncounterState(
|
||||||
|
data: EncounterData<"minion" | "elite">,
|
||||||
|
): CombatEncounterState {
|
||||||
|
return { data, blocked: false };
|
||||||
|
}
|
||||||
|
|
||||||
function createEnemyEntities(encounter: EncounterData): EnemyEntity[] {
|
function createEnemyEntities(encounter: EncounterData): EnemyEntity[] {
|
||||||
const enemies: EnemyEntity[] = [];
|
const enemies: EnemyEntity[] = [];
|
||||||
let instanceCounter = 0;
|
let instanceCounter = 0;
|
||||||
|
|
@ -87,18 +96,18 @@ function buildEffectTable(buffs: readonly [EffectData, number][]): EffectTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPlayerEntity(
|
function createPlayerEntity(
|
||||||
playerState: IPlayerState,
|
runState: RunState,
|
||||||
deck: IPlayerDeck,
|
deck: ReturnType<typeof generateDeckFromInventory>,
|
||||||
): PlayerEntity {
|
): PlayerEntity {
|
||||||
return {
|
return {
|
||||||
id: "player",
|
id: "player",
|
||||||
hp: playerState.hp,
|
hp: runState.currentHp,
|
||||||
maxHp: playerState.maxHp,
|
maxHp: runState.maxHp,
|
||||||
isAlive: playerState.hp > 0,
|
isAlive: runState.currentHp > 0,
|
||||||
energy: 3,
|
energy: 3,
|
||||||
maxEnergy: 3,
|
maxEnergy: 3,
|
||||||
deck,
|
deck,
|
||||||
itemEffects: playerState.itemEffects,
|
itemEffects: {},
|
||||||
effects: {},
|
effects: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
import { createGridInventory, placeItem } from "../grid-inventory";
|
||||||
|
import { GameItemMeta } from "../grid-inventory/types";
|
||||||
|
import { IDENTITY_TRANSFORM } from "../utils/shape-collision";
|
||||||
|
import { parseShapeString } from "../utils/parse-shape";
|
||||||
|
import { EncounterData, EncounterType, ItemData } from "../types";
|
||||||
|
import type { RNG } from "@/utils/rng";
|
||||||
|
import type {
|
||||||
|
CampEncounterState,
|
||||||
|
CombatEncounterState,
|
||||||
|
CurioEncounterState,
|
||||||
|
DialogueEncounterState,
|
||||||
|
EncounterState,
|
||||||
|
ShopEncounterState,
|
||||||
|
} from "./types";
|
||||||
|
import { buildCombatEncounterState } from "./combat";
|
||||||
|
import { buildShopEncounterState } from "./shop";
|
||||||
|
|
||||||
|
function createCurioItems(allItems: ItemData[], rng: RNG): GameItemMeta[] {
|
||||||
|
const curioItems: GameItemMeta[] = [];
|
||||||
|
const rolledIndices = new Set<number>();
|
||||||
|
|
||||||
|
for (let i = 0; i < 3 && rolledIndices.size < allItems.length; i++) {
|
||||||
|
let index: number;
|
||||||
|
do {
|
||||||
|
index = rng.nextInt(allItems.length);
|
||||||
|
} while (rolledIndices.has(index));
|
||||||
|
rolledIndices.add(index);
|
||||||
|
|
||||||
|
const itemData = allItems[index];
|
||||||
|
const shape = parseShapeString(itemData.shape);
|
||||||
|
curioItems.push({ itemData, shape });
|
||||||
|
}
|
||||||
|
|
||||||
|
return curioItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildCurioEncounterState(
|
||||||
|
data: EncounterData<"curio">,
|
||||||
|
allItems: ItemData[],
|
||||||
|
rng: RNG,
|
||||||
|
): CurioEncounterState {
|
||||||
|
const items = createCurioItems(allItems, rng);
|
||||||
|
const inventory = createGridInventory<GameItemMeta>(6, 4);
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const meta = items[i];
|
||||||
|
placeItem(inventory, {
|
||||||
|
id: `curio-item-${i}`,
|
||||||
|
shape: meta.shape,
|
||||||
|
transform: { ...IDENTITY_TRANSFORM, offset: { x: i, y: 0 } },
|
||||||
|
meta,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { data, items: inventory };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildCampEncounterState(
|
||||||
|
data: EncounterData<"camp">,
|
||||||
|
): CampEncounterState {
|
||||||
|
return { data };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildDialogueEncounterState(
|
||||||
|
data: EncounterData<"event">,
|
||||||
|
): DialogueEncounterState {
|
||||||
|
return { data, blocked: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildEncounterState(
|
||||||
|
data: EncounterData<EncounterType>,
|
||||||
|
allItems: ItemData[],
|
||||||
|
rng: RNG,
|
||||||
|
idCounter: { value: number },
|
||||||
|
): EncounterState {
|
||||||
|
switch (data.type) {
|
||||||
|
case "minion":
|
||||||
|
case "elite":
|
||||||
|
return buildCombatEncounterState(
|
||||||
|
data as EncounterData<"minion" | "elite">,
|
||||||
|
);
|
||||||
|
case "shop":
|
||||||
|
return buildShopEncounterState(
|
||||||
|
data as EncounterData<"shop">,
|
||||||
|
allItems,
|
||||||
|
rng,
|
||||||
|
idCounter,
|
||||||
|
);
|
||||||
|
case "curio":
|
||||||
|
return buildCurioEncounterState(
|
||||||
|
data as EncounterData<"curio">,
|
||||||
|
allItems,
|
||||||
|
rng,
|
||||||
|
);
|
||||||
|
case "camp":
|
||||||
|
return buildCampEncounterState(data as EncounterData<"camp">);
|
||||||
|
case "event":
|
||||||
|
return buildDialogueEncounterState(data as EncounterData<"event">);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
export * from "./types";
|
export { buildCombatState, buildCombatEncounterState } from "./combat";
|
||||||
export * from "./run";
|
export { buildShopEncounterState, generateInstanceId } from "./shop";
|
||||||
|
export { buildEncounterState } from "./encounter";
|
||||||
|
export { RunState, EncounterState } from "./types";
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { RunState } from "./types";
|
||||||
const DEFAULT_MAX_HP = 50;
|
const DEFAULT_MAX_HP = 50;
|
||||||
const DEFAULT_GOLD = 50;
|
const DEFAULT_GOLD = 50;
|
||||||
|
|
||||||
export function createRunState(): RunState {
|
export function createRunState(startNode: string): RunState {
|
||||||
return {
|
return {
|
||||||
maxHp: DEFAULT_MAX_HP,
|
maxHp: DEFAULT_MAX_HP,
|
||||||
currentHp: DEFAULT_MAX_HP,
|
currentHp: DEFAULT_MAX_HP,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import { createGridInventory, placeItem } from "../grid-inventory";
|
||||||
|
import { GameItemMeta } from "../grid-inventory/types";
|
||||||
|
import { IDENTITY_TRANSFORM } from "../utils/shape-collision";
|
||||||
|
import { parseShapeString } from "../utils/parse-shape";
|
||||||
|
import { EncounterData, ItemData } from "../types";
|
||||||
|
import type { RNG } from "@/utils/rng";
|
||||||
|
import type { ShopEncounterState } from "./types";
|
||||||
|
|
||||||
|
export function generateInstanceId(counter: { value: number }): string {
|
||||||
|
counter.value++;
|
||||||
|
return `item-${counter.value}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createShopItems(
|
||||||
|
allItems: ItemData[],
|
||||||
|
rng: RNG,
|
||||||
|
): (GameItemMeta & { sellPrice: number })[] {
|
||||||
|
const shopItems: (GameItemMeta & { sellPrice: number })[] = [];
|
||||||
|
const rolledIndices = new Set<number>();
|
||||||
|
|
||||||
|
for (let i = 0; i < 5 && rolledIndices.size < allItems.length; i++) {
|
||||||
|
let index: number;
|
||||||
|
do {
|
||||||
|
index = rng.nextInt(allItems.length);
|
||||||
|
} while (rolledIndices.has(index));
|
||||||
|
rolledIndices.add(index);
|
||||||
|
|
||||||
|
const itemData = allItems[index];
|
||||||
|
const shape = parseShapeString(itemData.shape);
|
||||||
|
const sellPrice = Math.floor(
|
||||||
|
(rng.nextInt(5) + rng.nextInt(5) + 1) * 0.2 * itemData.price,
|
||||||
|
);
|
||||||
|
|
||||||
|
shopItems.push({ itemData, shape, sellPrice });
|
||||||
|
}
|
||||||
|
|
||||||
|
return shopItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildShopEncounterState(
|
||||||
|
data: EncounterData<"shop">,
|
||||||
|
allItems: ItemData[],
|
||||||
|
rng: RNG,
|
||||||
|
idCounter: { value: number },
|
||||||
|
): ShopEncounterState {
|
||||||
|
const items = createShopItems(allItems, rng);
|
||||||
|
const inventory = createGridInventory<GameItemMeta & { sellPrice: number }>(
|
||||||
|
6,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const meta = items[i];
|
||||||
|
placeItem(inventory, {
|
||||||
|
id: generateInstanceId(idCounter),
|
||||||
|
shape: meta.shape,
|
||||||
|
transform: { ...IDENTITY_TRANSFORM, offset: { x: i, y: 0 } },
|
||||||
|
meta,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { data, items: inventory };
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { parseShapeString } from "../utils/parse-shape";
|
import { parseShapeString } from "../utils/parse-shape";
|
||||||
import type { ParsedShape } from "../utils/parse-shape";
|
import type { ParsedShape } from "../utils/parse-shape";
|
||||||
import { IDENTITY_TRANSFORM, type Transform2D } from "../utils/shape-collision";
|
import type { Transform2D } from "../utils/shape-collision";
|
||||||
import { createGridInventory, placeItem, validatePlacement } from "./transform";
|
import { placeItem, validatePlacement } from "./transform";
|
||||||
import type { GameItemMeta, GridInventory, MutationResult } from "./types";
|
import type { GameItemMeta, GridInventory, MutationResult } from "./types";
|
||||||
import type { ItemData } from "../types";
|
import type { ItemData } from "../types";
|
||||||
import { ReadonlyRNG, RNG } from "@/utils/rng";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and places a GameItemMeta item into the grid inventory.
|
* Creates and places a GameItemMeta item into the grid inventory.
|
||||||
|
|
@ -14,16 +13,15 @@ import { ReadonlyRNG, RNG } from "@/utils/rng";
|
||||||
export function createItemIn(
|
export function createItemIn(
|
||||||
inventory: GridInventory<GameItemMeta>,
|
inventory: GridInventory<GameItemMeta>,
|
||||||
id: string,
|
id: string,
|
||||||
item: ItemData | GameItemMeta,
|
itemData: ItemData,
|
||||||
): MutationResult {
|
): MutationResult {
|
||||||
const itemData = "itemData" in item ? item.itemData : item;
|
|
||||||
const shape = parseShapeString(itemData.shape);
|
const shape = parseShapeString(itemData.shape);
|
||||||
const transform = findFirstValidPlacement(inventory, shape);
|
const transform = findFirstValidPlacement(inventory, shape);
|
||||||
if (!transform) {
|
if (!transform) {
|
||||||
return { success: false, reason: "无可用位置" };
|
return { success: false, reason: "无可用位置" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta: GameItemMeta = "itemData" in item ? item : { itemData, shape };
|
const meta: GameItemMeta = { itemData, shape };
|
||||||
placeItem(inventory, { id, shape, transform, meta });
|
placeItem(inventory, { id, shape, transform, meta });
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
@ -52,70 +50,3 @@ function findFirstValidPlacement(
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateInstanceId(counter: { value: number }): string {
|
|
||||||
counter.value++;
|
|
||||||
return `item-${counter.value}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createShopInventory(
|
|
||||||
allItems: ItemData[],
|
|
||||||
rng: ReadonlyRNG,
|
|
||||||
counter: { value: number },
|
|
||||||
) {
|
|
||||||
const shopItems: GameItemMeta[] = [];
|
|
||||||
const rolledIndices = new Set<number>();
|
|
||||||
|
|
||||||
for (let i = 0; i < 5 && rolledIndices.size < allItems.length; i++) {
|
|
||||||
let index: number;
|
|
||||||
do {
|
|
||||||
index = rng.nextInt(allItems.length);
|
|
||||||
} while (rolledIndices.has(index));
|
|
||||||
rolledIndices.add(index);
|
|
||||||
|
|
||||||
const itemData = allItems[index];
|
|
||||||
const shape = parseShapeString(itemData.shape);
|
|
||||||
const tradePrice = Math.floor(
|
|
||||||
(rng.nextInt(5) + rng.nextInt(5) + 1) * 0.2 * itemData.price,
|
|
||||||
);
|
|
||||||
|
|
||||||
shopItems.push({ itemData, shape, tradePrice });
|
|
||||||
}
|
|
||||||
|
|
||||||
const inventory = createGridInventory<GameItemMeta>(6, 4);
|
|
||||||
|
|
||||||
for (let i = 0; i < shopItems.length; i++) {
|
|
||||||
createItemIn(inventory, generateInstanceId(counter), shopItems[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createCurioItems(
|
|
||||||
allItems: ItemData[],
|
|
||||||
rng: RNG,
|
|
||||||
counter: { value: number },
|
|
||||||
) {
|
|
||||||
const curioItems: GameItemMeta[] = [];
|
|
||||||
const rolledIndices = new Set<number>();
|
|
||||||
|
|
||||||
for (let i = 0; i < 2 && rolledIndices.size < allItems.length; i++) {
|
|
||||||
let index: number;
|
|
||||||
do {
|
|
||||||
index = rng.nextInt(allItems.length);
|
|
||||||
} while (rolledIndices.has(index));
|
|
||||||
rolledIndices.add(index);
|
|
||||||
|
|
||||||
const itemData = allItems[index];
|
|
||||||
const shape = parseShapeString(itemData.shape);
|
|
||||||
curioItems.push({ itemData, shape });
|
|
||||||
}
|
|
||||||
|
|
||||||
const inventory = createGridInventory<GameItemMeta>(4, 3);
|
|
||||||
|
|
||||||
for (let i = 0; i < curioItems.length; i++) {
|
|
||||||
createItemIn(inventory, generateInstanceId(counter), curioItems[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,4 @@ export {
|
||||||
validatePlacement,
|
validatePlacement,
|
||||||
} from "./transform";
|
} from "./transform";
|
||||||
|
|
||||||
export * from "./factory";
|
export { createItemIn } from "./factory";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue