feat(bgm): model setup as ordered placements
Replace the path->parts setup map with an ordered list of placements, each moving its parts to a path. Entries apply in order, so a part listed in a later placement ends up on that placement's path.
This commit is contained in:
@@ -103,6 +103,8 @@ surfaces:
|
|||||||
- board#harbor
|
- board#harbor
|
||||||
- board#player
|
- board#player
|
||||||
setup:
|
setup:
|
||||||
/dock/0: harbor:token#wood
|
- path: /dock/0
|
||||||
/deck: harbor:token#grain
|
parts: harbor:token#wood
|
||||||
|
- path: /deck
|
||||||
|
parts: harbor:token#grain
|
||||||
```
|
```
|
||||||
@@ -48,5 +48,6 @@ role: setup
|
|||||||
type: game
|
type: game
|
||||||
id: main
|
id: main
|
||||||
setup:
|
setup:
|
||||||
/factory/0: azul:tile#blue
|
- path: /factory/0
|
||||||
|
parts: azul:tile#blue
|
||||||
```
|
```
|
||||||
@@ -53,6 +53,8 @@ role: setup
|
|||||||
type: game
|
type: game
|
||||||
id: main
|
id: main
|
||||||
setup:
|
setup:
|
||||||
/dock/0: harbor:token#wood
|
- path: /dock/0
|
||||||
/deck: harbor:token#grain
|
parts: harbor:token#wood
|
||||||
|
- path: /deck
|
||||||
|
parts: harbor:token#grain
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -55,10 +55,10 @@ describe('collectPackages', () => {
|
|||||||
expect([...harbor.setups.keys()]).toEqual(['game#main']);
|
expect([...harbor.setups.keys()]).toEqual(['game#main']);
|
||||||
const setup = harbor.setups.get('game#main')!;
|
const setup = harbor.setups.get('game#main')!;
|
||||||
expect(setup.surfaces).toEqual(['board#harbor', 'board#player']);
|
expect(setup.surfaces).toEqual(['board#harbor', 'board#player']);
|
||||||
expect(setup.setup).toEqual({
|
expect(setup.setup).toEqual([
|
||||||
'/dock/0': 'harbor:token#wood',
|
{ path: '/dock/0', parts: 'harbor:token#wood' },
|
||||||
'/deck': 'harbor:token#grain',
|
{ path: '/deck', parts: 'harbor:token#grain' },
|
||||||
});
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('scopes include patterns to the package declaration directory', () => {
|
it('scopes include patterns to the package declaration directory', () => {
|
||||||
|
|||||||
@@ -60,11 +60,18 @@ const surfaceSchema = z.object({
|
|||||||
layout: z.array(route),
|
layout: z.array(route),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const setupValue = z.union([z.string(), z.array(z.string())]);
|
||||||
|
|
||||||
|
const setupPlacement = z.object({
|
||||||
|
path: z.string(),
|
||||||
|
parts: setupValue,
|
||||||
|
});
|
||||||
|
|
||||||
const setupSchema = z.object({
|
const setupSchema = z.object({
|
||||||
type: z.string().min(1),
|
type: z.string().min(1),
|
||||||
id: z.string().min(1),
|
id: z.string().min(1),
|
||||||
surfaces: z.array(z.string()).optional(),
|
surfaces: z.array(z.string()).optional(),
|
||||||
setup: z.record(z.string(), z.union([z.string(), z.array(z.string())])),
|
setup: z.array(setupPlacement),
|
||||||
});
|
});
|
||||||
|
|
||||||
const packageSchema = z.object({
|
const packageSchema = z.object({
|
||||||
|
|||||||
@@ -157,13 +157,25 @@ export interface Surface {
|
|||||||
|
|
||||||
export type SetupValue = string | string[];
|
export type SetupValue = string | string[];
|
||||||
|
|
||||||
/** Seeds the state store: the enabled surfaces and a map from path to parts. */
|
/**
|
||||||
|
* One setup placement: move `parts` to `path`. Entries are applied in order,
|
||||||
|
* so a part listed in a later entry ends up on that entry's path.
|
||||||
|
*/
|
||||||
|
export interface SetupPlacement {
|
||||||
|
/** The path key to place the parts on. */
|
||||||
|
path: string;
|
||||||
|
/** Parts to place: a part id, a bare type (expands to all of that type), or a list of either. */
|
||||||
|
parts: SetupValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Seeds the state store: the enabled surfaces and an ordered list of placements. */
|
||||||
export interface Setup {
|
export interface Setup {
|
||||||
type: string;
|
type: string;
|
||||||
id: string;
|
id: string;
|
||||||
/** Surfaces (`type#id` refs) enabled at the start; omitted = all enabled. */
|
/** Surfaces (`type#id` refs) enabled at the start; omitted = all enabled. */
|
||||||
surfaces?: string[];
|
surfaces?: string[];
|
||||||
setup: Record<string, SetupValue>;
|
/** Ordered placements; each moves its parts to its path. */
|
||||||
|
setup: SetupPlacement[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Role = 'package' | 'part' | 'surface' | 'setup';
|
export type Role = 'package' | 'part' | 'surface' | 'setup';
|
||||||
|
|||||||
Reference in New Issue
Block a user