@sharpee/world-model 0.9.111 → 1.0.0
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.
- package/capabilities/action-interceptor.d.ts +122 -6
- package/capabilities/action-interceptor.d.ts.map +1 -1
- package/capabilities/action-interceptor.js +59 -0
- package/capabilities/action-interceptor.js.map +1 -1
- package/capabilities/index.d.ts +1 -1
- package/capabilities/index.d.ts.map +1 -1
- package/capabilities/index.js +11 -1
- package/capabilities/index.js.map +1 -1
- package/entities/entity-types.d.ts +2 -0
- package/entities/entity-types.d.ts.map +1 -1
- package/entities/entity-types.js +3 -0
- package/entities/entity-types.js.map +1 -1
- package/entities/index.d.ts +2 -0
- package/entities/index.d.ts.map +1 -1
- package/entities/index.js +3 -1
- package/entities/index.js.map +1 -1
- package/entities/wall-entity.d.ts +112 -0
- package/entities/wall-entity.d.ts.map +1 -0
- package/entities/wall-entity.js +50 -0
- package/entities/wall-entity.js.map +1 -0
- package/index.d.ts +3 -0
- package/index.d.ts.map +1 -1
- package/index.js +3 -0
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/traits/acoustic/acousticDampenerTrait.d.ts +61 -0
- package/traits/acoustic/acousticDampenerTrait.d.ts.map +1 -0
- package/traits/acoustic/acousticDampenerTrait.js +38 -0
- package/traits/acoustic/acousticDampenerTrait.js.map +1 -0
- package/traits/acoustic/acousticTrait.d.ts +64 -0
- package/traits/acoustic/acousticTrait.d.ts.map +1 -0
- package/traits/acoustic/acousticTrait.js +47 -0
- package/traits/acoustic/acousticTrait.js.map +1 -0
- package/traits/acoustic/index.d.ts +3 -0
- package/traits/acoustic/index.d.ts.map +1 -0
- package/traits/acoustic/index.js +10 -0
- package/traits/acoustic/index.js.map +1 -0
- package/traits/implementations.d.ts.map +1 -1
- package/traits/implementations.js +8 -0
- package/traits/implementations.js.map +1 -1
- package/traits/index.d.ts +3 -0
- package/traits/index.d.ts.map +1 -1
- package/traits/index.js +5 -0
- package/traits/index.js.map +1 -1
- package/traits/listener/index.d.ts +2 -0
- package/traits/listener/index.d.ts.map +1 -0
- package/traits/listener/index.js +7 -0
- package/traits/listener/index.js.map +1 -0
- package/traits/listener/listenerTrait.d.ts +40 -0
- package/traits/listener/listenerTrait.d.ts.map +1 -0
- package/traits/listener/listenerTrait.js +23 -0
- package/traits/listener/listenerTrait.js.map +1 -0
- package/traits/obstructor-protocol.d.ts +96 -0
- package/traits/obstructor-protocol.d.ts.map +1 -0
- package/traits/obstructor-protocol.js +77 -0
- package/traits/obstructor-protocol.js.map +1 -0
- package/traits/room/roomTrait.d.ts +7 -0
- package/traits/room/roomTrait.d.ts.map +1 -1
- package/traits/room/roomTrait.js +2 -0
- package/traits/room/roomTrait.js.map +1 -1
- package/traits/story-info/storyInfoTrait.d.ts +6 -0
- package/traits/story-info/storyInfoTrait.d.ts.map +1 -1
- package/traits/story-info/storyInfoTrait.js +6 -0
- package/traits/story-info/storyInfoTrait.js.map +1 -1
- package/traits/trait-types.d.ts +3 -0
- package/traits/trait-types.d.ts.map +1 -1
- package/traits/trait-types.js +8 -0
- package/traits/trait-types.js.map +1 -1
- package/world/AuthorModel.d.ts +3 -0
- package/world/AuthorModel.d.ts.map +1 -1
- package/world/AuthorModel.js +7 -0
- package/world/AuthorModel.js.map +1 -1
- package/world/WorldModel.d.ts +23 -0
- package/world/WorldModel.d.ts.map +1 -1
- package/world/WorldModel.js +36 -0
- package/world/WorldModel.js.map +1 -1
- package/world/index.d.ts +4 -0
- package/world/index.d.ts.map +1 -1
- package/world/index.js +7 -1
- package/world/index.js.map +1 -1
- package/world/wall-creation.d.ts +38 -0
- package/world/wall-creation.d.ts.map +1 -0
- package/world/wall-creation.js +98 -0
- package/world/wall-creation.js.map +1 -0
- package/world/wall-validation.d.ts +45 -0
- package/world/wall-validation.d.ts.map +1 -0
- package/world/wall-validation.js +98 -0
- package/world/wall-validation.js.map +1 -0
package/world/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/world-model/src/world/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EAEd,iBAAiB,EACjB,iBAAiB,EAEjB,UAAU,EAEV,aAAa,EACb,eAAe,EAEf,YAAY,EACZ,eAAe,EAChB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGnE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/world-model/src/world/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EAEd,iBAAiB,EACjB,iBAAiB,EAEjB,UAAU,EAEV,aAAa,EACb,eAAe,EAEf,YAAY,EACZ,eAAe,EAChB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,gBAAgB,CAAC"}
|
package/world/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// index.ts - World model exports
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.StandardCapabilities = exports.AuthorModel = exports.VisibilityBehavior = exports.SpatialIndex = exports.GrammarVocabularyProvider = exports.WorldModel = void 0;
|
|
4
|
+
exports.StandardCapabilities = exports.validateWallSpec = exports.createWalls = exports.createWall = exports.AuthorModel = exports.VisibilityBehavior = exports.SpatialIndex = exports.GrammarVocabularyProvider = exports.WorldModel = void 0;
|
|
5
5
|
// Export all types and the WorldModel interface/class from the same file
|
|
6
6
|
var WorldModel_1 = require("./WorldModel");
|
|
7
7
|
Object.defineProperty(exports, "WorldModel", { enumerable: true, get: function () { return WorldModel_1.WorldModel; } });
|
|
@@ -15,6 +15,12 @@ var VisibilityBehavior_1 = require("./VisibilityBehavior");
|
|
|
15
15
|
Object.defineProperty(exports, "VisibilityBehavior", { enumerable: true, get: function () { return VisibilityBehavior_1.VisibilityBehavior; } });
|
|
16
16
|
var AuthorModel_1 = require("./AuthorModel");
|
|
17
17
|
Object.defineProperty(exports, "AuthorModel", { enumerable: true, get: function () { return AuthorModel_1.AuthorModel; } });
|
|
18
|
+
// Wall Adjacency (ADR-173)
|
|
19
|
+
var wall_creation_1 = require("./wall-creation");
|
|
20
|
+
Object.defineProperty(exports, "createWall", { enumerable: true, get: function () { return wall_creation_1.createWall; } });
|
|
21
|
+
Object.defineProperty(exports, "createWalls", { enumerable: true, get: function () { return wall_creation_1.createWalls; } });
|
|
22
|
+
var wall_validation_1 = require("./wall-validation");
|
|
23
|
+
Object.defineProperty(exports, "validateWallSpec", { enumerable: true, get: function () { return wall_validation_1.validateWallSpec; } });
|
|
18
24
|
// Export capability types
|
|
19
25
|
var capabilities_1 = require("./capabilities");
|
|
20
26
|
Object.defineProperty(exports, "StandardCapabilities", { enumerable: true, get: function () { return capabilities_1.StandardCapabilities; } });
|
package/world/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/world-model/src/world/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;;;AAEjC,yEAAyE;AACzE,2CAqBsB;AApBpB,wGAAA,UAAU,OAAA;AAsBZ,oEAAoE;AACpE,gDAK4B;AAH1B,sHAAA,yBAAyB,OAAA;AAK3B,uBAAuB;AACvB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,6CAAmE;AAA1D,0GAAA,WAAW,OAAA;AAEpB,0BAA0B;AAC1B,+CAOwB;AAFtB,oHAAA,oBAAoB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/world-model/src/world/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;;;AAEjC,yEAAyE;AACzE,2CAqBsB;AApBpB,wGAAA,UAAU,OAAA;AAsBZ,oEAAoE;AACpE,gDAK4B;AAH1B,sHAAA,yBAAyB,OAAA;AAK3B,uBAAuB;AACvB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,6CAAmE;AAA1D,0GAAA,WAAW,OAAA;AAEpB,2BAA2B;AAC3B,iDAA0D;AAAjD,2GAAA,UAAU,OAAA;AAAE,4GAAA,WAAW,OAAA;AAEhC,qDAAqD;AAA5C,mHAAA,gBAAgB,OAAA;AAGzB,0BAA0B;AAC1B,+CAOwB;AAFtB,oHAAA,oBAAoB,OAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { IFEntity } from '../entities/if-entity';
|
|
2
|
+
import { WallEntity, IWallSpec, IWallsSpec } from '../entities/wall-entity';
|
|
3
|
+
/**
|
|
4
|
+
* The narrow world surface required for wall creation. Implemented by
|
|
5
|
+
* `WorldModel`; not part of the public IWorldModel interface.
|
|
6
|
+
*/
|
|
7
|
+
export interface IWallCreationWorld {
|
|
8
|
+
getEntity(id: string): IFEntity | undefined;
|
|
9
|
+
getLocation(entityId: string): string | undefined;
|
|
10
|
+
generateWallId(): string;
|
|
11
|
+
registerWall(wall: WallEntity): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a single wall between exactly two distinct rooms (ADR-173).
|
|
15
|
+
*
|
|
16
|
+
* Validates the spec (cardinality, per-side adjectives, per-room
|
|
17
|
+
* adjective uniqueness, obstructor resolution), builds a `WallEntity`
|
|
18
|
+
* carrying any whole-wall traits and per-side data, registers it in
|
|
19
|
+
* the world, and pushes its id into both rooms' `RoomTrait.walls`
|
|
20
|
+
* collections.
|
|
21
|
+
*
|
|
22
|
+
* @throws Error on any validation failure (see `validateWallSpec`).
|
|
23
|
+
*/
|
|
24
|
+
export declare function createWall(world: IWallCreationWorld, spec: IWallSpec): WallEntity;
|
|
25
|
+
/**
|
|
26
|
+
* Convenience helper that fans out into N walls between `from` and
|
|
27
|
+
* each room in `to` (ADR-173 §Authoring API). Each underlying wall is
|
|
28
|
+
* created with the supplied whole-wall traits (cloned per call to
|
|
29
|
+
* avoid sharing trait instances across walls) and per-side data
|
|
30
|
+
* produced by the `sides` callback.
|
|
31
|
+
*
|
|
32
|
+
* Walls are created sequentially. If validation fails on the K-th
|
|
33
|
+
* pair, walls 0..K-1 are already in the world — author is expected
|
|
34
|
+
* to fix the offending pair and re-run only the bad declaration, in
|
|
35
|
+
* keeping with ADR-173's load-time-failure model.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createWalls(world: IWallCreationWorld, spec: IWallsSpec): WallEntity[];
|
|
38
|
+
//# sourceMappingURL=wall-creation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-creation.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/world-model/src/world/wall-creation.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EACL,UAAU,EACV,SAAS,EACT,UAAU,EAEX,MAAM,yBAAyB,CAAC;AAMjC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,cAAc,IAAI,MAAM,CAAC;IACzB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;CACtC;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,kBAAkB,EACzB,IAAI,EAAE,SAAS,GACd,UAAU,CAkCZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,kBAAkB,EACzB,IAAI,EAAE,UAAU,GACf,UAAU,EAAE,CAoBd"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// packages/world-model/src/world/wall-creation.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.createWall = createWall;
|
|
5
|
+
exports.createWalls = createWalls;
|
|
6
|
+
const wall_entity_1 = require("../entities/wall-entity");
|
|
7
|
+
const trait_types_1 = require("../traits/trait-types");
|
|
8
|
+
const wall_validation_1 = require("./wall-validation");
|
|
9
|
+
function refToId(ref) {
|
|
10
|
+
return typeof ref === 'string' ? ref : ref.id;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a single wall between exactly two distinct rooms (ADR-173).
|
|
14
|
+
*
|
|
15
|
+
* Validates the spec (cardinality, per-side adjectives, per-room
|
|
16
|
+
* adjective uniqueness, obstructor resolution), builds a `WallEntity`
|
|
17
|
+
* carrying any whole-wall traits and per-side data, registers it in
|
|
18
|
+
* the world, and pushes its id into both rooms' `RoomTrait.walls`
|
|
19
|
+
* collections.
|
|
20
|
+
*
|
|
21
|
+
* @throws Error on any validation failure (see `validateWallSpec`).
|
|
22
|
+
*/
|
|
23
|
+
function createWall(world, spec) {
|
|
24
|
+
const { roomAId, roomBId, roomA, roomB } = (0, wall_validation_1.validateWallSpec)(spec, world);
|
|
25
|
+
const wallId = world.generateWallId();
|
|
26
|
+
const wall = new wall_entity_1.WallEntity(wallId, [roomAId, roomBId], {
|
|
27
|
+
attributes: {
|
|
28
|
+
displayName: 'wall',
|
|
29
|
+
name: 'wall',
|
|
30
|
+
entityType: 'wall',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
if (spec.whole) {
|
|
34
|
+
for (const trait of spec.whole) {
|
|
35
|
+
wall.add(trait);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
wall.sides.set(roomAId, { ...spec.sides[roomAId] });
|
|
39
|
+
wall.sides.set(roomBId, { ...spec.sides[roomBId] });
|
|
40
|
+
// ADR-173 Phase 3 — make the wall reachable for parser/validator scope from
|
|
41
|
+
// either connecting room. Walls have no spatial containment, so the default
|
|
42
|
+
// scope rules (room contents + the room itself) do not include them. Numeric
|
|
43
|
+
// 2 corresponds to ScopeLevel.VISIBLE (see if-entity.ts setMinimumScope).
|
|
44
|
+
wall.setMinimumScope(2, [roomAId, roomBId]);
|
|
45
|
+
world.registerWall(wall);
|
|
46
|
+
pushWallId(roomA, wallId);
|
|
47
|
+
pushWallId(roomB, wallId);
|
|
48
|
+
return wall;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Convenience helper that fans out into N walls between `from` and
|
|
52
|
+
* each room in `to` (ADR-173 §Authoring API). Each underlying wall is
|
|
53
|
+
* created with the supplied whole-wall traits (cloned per call to
|
|
54
|
+
* avoid sharing trait instances across walls) and per-side data
|
|
55
|
+
* produced by the `sides` callback.
|
|
56
|
+
*
|
|
57
|
+
* Walls are created sequentially. If validation fails on the K-th
|
|
58
|
+
* pair, walls 0..K-1 are already in the world — author is expected
|
|
59
|
+
* to fix the offending pair and re-run only the bad declaration, in
|
|
60
|
+
* keeping with ADR-173's load-time-failure model.
|
|
61
|
+
*/
|
|
62
|
+
function createWalls(world, spec) {
|
|
63
|
+
const fromId = refToId(spec.from);
|
|
64
|
+
const walls = [];
|
|
65
|
+
for (const toRef of spec.to) {
|
|
66
|
+
const toId = refToId(toRef);
|
|
67
|
+
const sides = {
|
|
68
|
+
[fromId]: spec.sides(fromId),
|
|
69
|
+
[toId]: spec.sides(toId),
|
|
70
|
+
};
|
|
71
|
+
const whole = spec.whole ? cloneTraits(spec.whole) : undefined;
|
|
72
|
+
const wall = createWall(world, {
|
|
73
|
+
between: [fromId, toId],
|
|
74
|
+
whole,
|
|
75
|
+
sides,
|
|
76
|
+
});
|
|
77
|
+
walls.push(wall);
|
|
78
|
+
}
|
|
79
|
+
return walls;
|
|
80
|
+
}
|
|
81
|
+
function pushWallId(room, wallId) {
|
|
82
|
+
const trait = room.get(trait_types_1.TraitType.ROOM);
|
|
83
|
+
if (!trait) {
|
|
84
|
+
throw new Error(`wall-creation: room '${room.id}' lost its RoomTrait between validation and mutation`);
|
|
85
|
+
}
|
|
86
|
+
if (!trait.walls) {
|
|
87
|
+
trait.walls = [];
|
|
88
|
+
}
|
|
89
|
+
trait.walls.push(wallId);
|
|
90
|
+
}
|
|
91
|
+
function cloneTraits(traits) {
|
|
92
|
+
return traits.map((t) => {
|
|
93
|
+
const proto = Object.getPrototypeOf(t);
|
|
94
|
+
const copy = Object.assign(Object.create(proto), t);
|
|
95
|
+
return copy;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=wall-creation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-creation.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/world-model/src/world/wall-creation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* World-load validation for wall specifications (ADR-173).
|
|
3
|
+
*
|
|
4
|
+
* Implements the Rejection rules from ADR-173 §"Rejection rules":
|
|
5
|
+
* cardinality (exactly two distinct rooms), per-side adjective
|
|
6
|
+
* presence/non-emptiness, per-room adjective uniqueness, and
|
|
7
|
+
* `obstructedBy` resolution against the world's current entity map.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: `validateWallSpec`. Pure validation — no mutation.
|
|
10
|
+
* Throws `Error` with a descriptive message on the first violation
|
|
11
|
+
* detected; never returns a structured error object (the validator is
|
|
12
|
+
* a precondition gate at the createWall boundary, not a recoverable
|
|
13
|
+
* subsystem).
|
|
14
|
+
*
|
|
15
|
+
* Owner context: `@sharpee/world-model` — world / spatial primitives.
|
|
16
|
+
*/
|
|
17
|
+
import { EntityId } from "../../core/index";
|
|
18
|
+
import { IFEntity } from '../entities/if-entity';
|
|
19
|
+
import { IWallSpec } from '../entities/wall-entity';
|
|
20
|
+
/**
|
|
21
|
+
* Read-only world surface this validator depends on. Limited to the
|
|
22
|
+
* methods required so the validator can be invoked from tests with a
|
|
23
|
+
* minimal stand-in if desired (and so it does not creep into mutation
|
|
24
|
+
* APIs by accident).
|
|
25
|
+
*/
|
|
26
|
+
export interface IWallValidationWorld {
|
|
27
|
+
getEntity(id: string): IFEntity | undefined;
|
|
28
|
+
getLocation(entityId: string): string | undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validates a wall specification before mutation.
|
|
32
|
+
*
|
|
33
|
+
* @param spec - The author-supplied wall specification.
|
|
34
|
+
* @param world - Read-only view of the world for entity/location lookups.
|
|
35
|
+
* @throws Error if cardinality, adjective presence, per-room adjective
|
|
36
|
+
* uniqueness, or `obstructedBy` resolution fails. The first failure
|
|
37
|
+
* detected aborts validation; no partial state escapes.
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateWallSpec(spec: IWallSpec, world: IWallValidationWorld): {
|
|
40
|
+
roomAId: EntityId;
|
|
41
|
+
roomBId: EntityId;
|
|
42
|
+
roomA: IFEntity;
|
|
43
|
+
roomB: IFEntity;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=wall-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-validation.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/world-model/src/world/wall-validation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAiB,MAAM,yBAAyB,CAAC;AAWnE;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,oBAAoB,GAC1B;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAsD5E"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// packages/world-model/src/world/wall-validation.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.validateWallSpec = validateWallSpec;
|
|
5
|
+
const trait_types_1 = require("../traits/trait-types");
|
|
6
|
+
/**
|
|
7
|
+
* Resolves an `IFEntity | EntityId` reference to its id string.
|
|
8
|
+
*/
|
|
9
|
+
function refToId(ref) {
|
|
10
|
+
return typeof ref === 'string' ? ref : ref.id;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Validates a wall specification before mutation.
|
|
14
|
+
*
|
|
15
|
+
* @param spec - The author-supplied wall specification.
|
|
16
|
+
* @param world - Read-only view of the world for entity/location lookups.
|
|
17
|
+
* @throws Error if cardinality, adjective presence, per-room adjective
|
|
18
|
+
* uniqueness, or `obstructedBy` resolution fails. The first failure
|
|
19
|
+
* detected aborts validation; no partial state escapes.
|
|
20
|
+
*/
|
|
21
|
+
function validateWallSpec(spec, world) {
|
|
22
|
+
if (!Array.isArray(spec.between)) {
|
|
23
|
+
throw new Error('createWall: `between` must be a tuple of exactly two rooms');
|
|
24
|
+
}
|
|
25
|
+
if (spec.between.length !== 2) {
|
|
26
|
+
throw new Error(`createWall: \`between\` must contain exactly 2 rooms (got ${spec.between.length})`);
|
|
27
|
+
}
|
|
28
|
+
const roomAId = refToId(spec.between[0]);
|
|
29
|
+
const roomBId = refToId(spec.between[1]);
|
|
30
|
+
if (roomAId === roomBId) {
|
|
31
|
+
throw new Error(`createWall: \`between\` must reference two distinct rooms (got self-reference '${roomAId}')`);
|
|
32
|
+
}
|
|
33
|
+
const roomA = world.getEntity(roomAId);
|
|
34
|
+
if (!roomA) {
|
|
35
|
+
throw new Error(`createWall: room '${roomAId}' does not exist`);
|
|
36
|
+
}
|
|
37
|
+
const roomB = world.getEntity(roomBId);
|
|
38
|
+
if (!roomB) {
|
|
39
|
+
throw new Error(`createWall: room '${roomBId}' does not exist`);
|
|
40
|
+
}
|
|
41
|
+
const roomATrait = roomA.get(trait_types_1.TraitType.ROOM);
|
|
42
|
+
if (!roomATrait) {
|
|
43
|
+
throw new Error(`createWall: entity '${roomAId}' is not a room`);
|
|
44
|
+
}
|
|
45
|
+
const roomBTrait = roomB.get(trait_types_1.TraitType.ROOM);
|
|
46
|
+
if (!roomBTrait) {
|
|
47
|
+
throw new Error(`createWall: entity '${roomBId}' is not a room`);
|
|
48
|
+
}
|
|
49
|
+
if (!spec.sides || typeof spec.sides !== 'object') {
|
|
50
|
+
throw new Error('createWall: `sides` must be a record keyed by room id');
|
|
51
|
+
}
|
|
52
|
+
const sideA = spec.sides[roomAId];
|
|
53
|
+
const sideB = spec.sides[roomBId];
|
|
54
|
+
validateSide(roomAId, sideA);
|
|
55
|
+
validateSide(roomBId, sideB);
|
|
56
|
+
validateAdjectiveUniqueness(roomAId, sideA.adjective, roomATrait, world);
|
|
57
|
+
validateAdjectiveUniqueness(roomBId, sideB.adjective, roomBTrait, world);
|
|
58
|
+
validateObstructor(roomAId, sideA, world);
|
|
59
|
+
validateObstructor(roomBId, sideB, world);
|
|
60
|
+
return { roomAId, roomBId, roomA, roomB };
|
|
61
|
+
}
|
|
62
|
+
function validateSide(roomId, side) {
|
|
63
|
+
if (!side) {
|
|
64
|
+
throw new Error(`createWall: missing per-side data for room '${roomId}'`);
|
|
65
|
+
}
|
|
66
|
+
if (typeof side.adjective !== 'string') {
|
|
67
|
+
throw new Error(`createWall: side for room '${roomId}' is missing a string \`adjective\``);
|
|
68
|
+
}
|
|
69
|
+
if (side.adjective.trim().length === 0) {
|
|
70
|
+
throw new Error(`createWall: side for room '${roomId}' has an empty \`adjective\``);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function validateAdjectiveUniqueness(roomId, adjective, roomTrait, world) {
|
|
74
|
+
const existingWallIds = roomTrait.walls ?? [];
|
|
75
|
+
for (const existingWallId of existingWallIds) {
|
|
76
|
+
const existing = world.getEntity(existingWallId);
|
|
77
|
+
if (!existing)
|
|
78
|
+
continue;
|
|
79
|
+
const sides = existing.sides;
|
|
80
|
+
const existingSide = sides?.get(roomId);
|
|
81
|
+
if (existingSide && existingSide.adjective === adjective) {
|
|
82
|
+
throw new Error(`createWall: adjective '${adjective}' is already used by another wall in room '${roomId}'`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function validateObstructor(roomId, side, world) {
|
|
87
|
+
if (side.obstructedBy === undefined)
|
|
88
|
+
return;
|
|
89
|
+
const obstructor = world.getEntity(side.obstructedBy);
|
|
90
|
+
if (!obstructor) {
|
|
91
|
+
throw new Error(`createWall: \`obstructedBy\` references nonexistent entity '${side.obstructedBy}' for room '${roomId}'`);
|
|
92
|
+
}
|
|
93
|
+
const obstructorLocation = world.getLocation(side.obstructedBy);
|
|
94
|
+
if (obstructorLocation !== roomId) {
|
|
95
|
+
throw new Error(`createWall: \`obstructedBy\` entity '${side.obstructedBy}' must be located in room '${roomId}' (currently in '${obstructorLocation ?? 'no location'}')`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=wall-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-validation.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/world-model/src/world/wall-validation.ts"],"names":[],"mappings":";AAAA,oDAAoD;;AAoDpD,4CAyDC;AAvFD,uDAAkD;AAGlD;;GAEG;AACH,SAAS,OAAO,CAAC,GAAwB;IACvC,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AAChD,CAAC;AAaD;;;;;;;;GAQG;AACH,SAAgB,gBAAgB,CAC9B,IAAe,EACf,KAA2B;IAE3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,6DAA6D,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CACpF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,kFAAkF,OAAO,IAAI,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,kBAAkB,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAY,uBAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,iBAAiB,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAY,uBAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,iBAAiB,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAElC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7B,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE7B,2BAA2B,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IACzE,2BAA2B,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAEzE,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1C,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAE1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,YAAY,CAAC,MAAgB,EAAE,IAA+B;IACrE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,8BAA8B,MAAM,qCAAqC,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,8BAA8B,MAAM,8BAA8B,CACnE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAClC,MAAgB,EAChB,SAAiB,EACjB,SAAoB,EACpB,KAA2B;IAE3B,MAAM,eAAe,GAAG,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9C,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,KAAK,GAAI,QAAgE,CAAC,KAAK,CAAC;QACtF,MAAM,YAAY,GAAG,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,YAAY,IAAI,YAAY,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,0BAA0B,SAAS,8CAA8C,MAAM,GAAG,CAC3F,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,MAAgB,EAChB,IAAmB,EACnB,KAA2B;IAE3B,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,+DAA+D,IAAI,CAAC,YAAY,eAAe,MAAM,GAAG,CACzG,CAAC;IACJ,CAAC;IACD,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChE,IAAI,kBAAkB,KAAK,MAAM,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,wCAAwC,IAAI,CAAC,YAAY,8BAA8B,MAAM,oBAAoB,kBAAkB,IAAI,aAAa,IAAI,CACzJ,CAAC;IACJ,CAAC;AACH,CAAC"}
|