@sharpee/event-processor 0.9.61-beta
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/LICENSE +21 -0
- package/README.md +43 -0
- package/dist-npm/effects/effect-processor.d.ts +50 -0
- package/dist-npm/effects/effect-processor.d.ts.map +1 -0
- package/dist-npm/effects/effect-processor.js +255 -0
- package/dist-npm/effects/effect-processor.js.map +1 -0
- package/dist-npm/effects/index.d.ts +10 -0
- package/dist-npm/effects/index.d.ts.map +1 -0
- package/dist-npm/effects/index.js +29 -0
- package/dist-npm/effects/index.js.map +1 -0
- package/dist-npm/effects/types.d.ts +119 -0
- package/dist-npm/effects/types.d.ts.map +1 -0
- package/dist-npm/effects/types.js +9 -0
- package/dist-npm/effects/types.js.map +1 -0
- package/dist-npm/effects/world-query.d.ts +70 -0
- package/dist-npm/effects/world-query.d.ts.map +1 -0
- package/dist-npm/effects/world-query.js +34 -0
- package/dist-npm/effects/world-query.js.map +1 -0
- package/dist-npm/handler-types.d.ts +67 -0
- package/dist-npm/handler-types.d.ts.map +1 -0
- package/dist-npm/handler-types.js +8 -0
- package/dist-npm/handler-types.js.map +1 -0
- package/dist-npm/handlers/complex-manipulation.d.ts +31 -0
- package/dist-npm/handlers/complex-manipulation.d.ts.map +1 -0
- package/dist-npm/handlers/complex-manipulation.js +87 -0
- package/dist-npm/handlers/complex-manipulation.js.map +1 -0
- package/dist-npm/handlers/device/index.d.ts +28 -0
- package/dist-npm/handlers/device/index.d.ts.map +1 -0
- package/dist-npm/handlers/device/index.js +172 -0
- package/dist-npm/handlers/device/index.js.map +1 -0
- package/dist-npm/handlers/index.d.ts +17 -0
- package/dist-npm/handlers/index.d.ts.map +1 -0
- package/dist-npm/handlers/index.js +48 -0
- package/dist-npm/handlers/index.js.map +1 -0
- package/dist-npm/handlers/meta.d.ts +59 -0
- package/dist-npm/handlers/meta.d.ts.map +1 -0
- package/dist-npm/handlers/meta.js +129 -0
- package/dist-npm/handlers/meta.js.map +1 -0
- package/dist-npm/handlers/movement.d.ts +51 -0
- package/dist-npm/handlers/movement.d.ts.map +1 -0
- package/dist-npm/handlers/movement.js +176 -0
- package/dist-npm/handlers/movement.js.map +1 -0
- package/dist-npm/handlers/observation/index.d.ts +6 -0
- package/dist-npm/handlers/observation/index.d.ts.map +1 -0
- package/dist-npm/handlers/observation/index.js +22 -0
- package/dist-npm/handlers/observation/index.js.map +1 -0
- package/dist-npm/handlers/observation/observation-handlers.d.ts +96 -0
- package/dist-npm/handlers/observation/observation-handlers.d.ts.map +1 -0
- package/dist-npm/handlers/observation/observation-handlers.js +162 -0
- package/dist-npm/handlers/observation/observation-handlers.js.map +1 -0
- package/dist-npm/handlers/observation/sensory.d.ts +29 -0
- package/dist-npm/handlers/observation/sensory.d.ts.map +1 -0
- package/dist-npm/handlers/observation/sensory.js +77 -0
- package/dist-npm/handlers/observation/sensory.js.map +1 -0
- package/dist-npm/handlers/state-change.d.ts +47 -0
- package/dist-npm/handlers/state-change.d.ts.map +1 -0
- package/dist-npm/handlers/state-change.js +166 -0
- package/dist-npm/handlers/state-change.js.map +1 -0
- package/dist-npm/index.d.ts +14 -0
- package/dist-npm/index.d.ts.map +1 -0
- package/dist-npm/index.js +32 -0
- package/dist-npm/index.js.map +1 -0
- package/dist-npm/processor.d.ts +62 -0
- package/dist-npm/processor.d.ts.map +1 -0
- package/dist-npm/processor.js +332 -0
- package/dist-npm/processor.js.map +1 -0
- package/dist-npm/types.d.ts +6 -0
- package/dist-npm/types.d.ts.map +1 -0
- package/dist-npm/types.js +6 -0
- package/dist-npm/types.js.map +1 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 David Cornelson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @sharpee/event-processor
|
|
2
|
+
|
|
3
|
+
Event processing and state application for the Sharpee Interactive Fiction platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @sharpee/event-processor
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Applies semantic events to the world model:
|
|
14
|
+
|
|
15
|
+
- **Event Application** - Updates world state based on events
|
|
16
|
+
- **Event Ordering** - Ensures consistent state transitions
|
|
17
|
+
- **Side Effects** - Triggers handlers for event types
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { EventProcessor } from '@sharpee/event-processor';
|
|
23
|
+
|
|
24
|
+
const processor = new EventProcessor(world);
|
|
25
|
+
|
|
26
|
+
// Apply events from action execution
|
|
27
|
+
const updatedWorld = processor.apply(events);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Event Flow
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Player Input → Parser → Action → Events → EventProcessor → Updated World
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Related Packages
|
|
37
|
+
|
|
38
|
+
- [@sharpee/engine](https://www.npmjs.com/package/@sharpee/engine) - Game runtime
|
|
39
|
+
- [@sharpee/sharpee](https://www.npmjs.com/package/@sharpee/sharpee) - Full platform bundle
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
MIT
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EffectProcessor: Validates and applies effects per ADR-075
|
|
3
|
+
*
|
|
4
|
+
* This is the ONLY place effects become mutations. It validates effects,
|
|
5
|
+
* ensures atomicity (all-or-nothing), and applies them through proper channels.
|
|
6
|
+
*/
|
|
7
|
+
import { ISemanticEvent } from '@sharpee/core';
|
|
8
|
+
import { WorldModel } from '@sharpee/world-model';
|
|
9
|
+
import { Effect, EffectResult } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Callback to emit events (provided by EventProcessor)
|
|
12
|
+
*/
|
|
13
|
+
export type EventEmitCallback = (events: ISemanticEvent[]) => void;
|
|
14
|
+
/**
|
|
15
|
+
* EffectProcessor validates and applies effects atomically
|
|
16
|
+
*/
|
|
17
|
+
export declare class EffectProcessor {
|
|
18
|
+
private world;
|
|
19
|
+
private emitEvents?;
|
|
20
|
+
constructor(world: WorldModel, emitEvents?: EventEmitCallback | undefined);
|
|
21
|
+
private pendingEmittedEvents;
|
|
22
|
+
/**
|
|
23
|
+
* Process effects with two-phase atomic processing
|
|
24
|
+
*
|
|
25
|
+
* Phase 1: Validate ALL effects before applying any
|
|
26
|
+
* Phase 2: Apply all effects (atomic - all or nothing)
|
|
27
|
+
*/
|
|
28
|
+
process(effects: Effect[]): EffectResult;
|
|
29
|
+
/**
|
|
30
|
+
* Validate all effects, returning any errors
|
|
31
|
+
*/
|
|
32
|
+
private validateAll;
|
|
33
|
+
/**
|
|
34
|
+
* Validate a single effect
|
|
35
|
+
*/
|
|
36
|
+
private validate;
|
|
37
|
+
/**
|
|
38
|
+
* Apply a single effect
|
|
39
|
+
*/
|
|
40
|
+
private apply;
|
|
41
|
+
private applyScoreEffect;
|
|
42
|
+
private applyFlagEffect;
|
|
43
|
+
private applyMessageEffect;
|
|
44
|
+
private applyEmitEffect;
|
|
45
|
+
private applyMoveEntityEffect;
|
|
46
|
+
private applyUpdateEntityEffect;
|
|
47
|
+
private applySetStateEffect;
|
|
48
|
+
private applyUpdateExitsEffect;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=effect-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-processor.d.ts","sourceRoot":"","sources":["../../src/effects/effect-processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAa,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EACL,MAAM,EAEN,YAAY,EASb,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;AAEnE;;GAEG;AACH,qBAAa,eAAe;IAExB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,UAAU,CAAC;gBADX,KAAK,EAAE,UAAU,EACjB,UAAU,CAAC,EAAE,iBAAiB,YAAA;IAIxC,OAAO,CAAC,oBAAoB,CAAwB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY;IAwBxC;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,OAAO,CAAC,QAAQ;IA2FhB;;OAEG;IACH,OAAO,CAAC,KAAK;IAgDb,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,sBAAsB;CAsB/B"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EffectProcessor: Validates and applies effects per ADR-075
|
|
4
|
+
*
|
|
5
|
+
* This is the ONLY place effects become mutations. It validates effects,
|
|
6
|
+
* ensures atomicity (all-or-nothing), and applies them through proper channels.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.EffectProcessor = void 0;
|
|
10
|
+
const world_model_1 = require("@sharpee/world-model");
|
|
11
|
+
/**
|
|
12
|
+
* EffectProcessor validates and applies effects atomically
|
|
13
|
+
*/
|
|
14
|
+
class EffectProcessor {
|
|
15
|
+
world;
|
|
16
|
+
emitEvents;
|
|
17
|
+
constructor(world, emitEvents) {
|
|
18
|
+
this.world = world;
|
|
19
|
+
this.emitEvents = emitEvents;
|
|
20
|
+
}
|
|
21
|
+
// Collect emitted events during processing
|
|
22
|
+
pendingEmittedEvents = [];
|
|
23
|
+
/**
|
|
24
|
+
* Process effects with two-phase atomic processing
|
|
25
|
+
*
|
|
26
|
+
* Phase 1: Validate ALL effects before applying any
|
|
27
|
+
* Phase 2: Apply all effects (atomic - all or nothing)
|
|
28
|
+
*/
|
|
29
|
+
process(effects) {
|
|
30
|
+
// Reset emitted events collector
|
|
31
|
+
this.pendingEmittedEvents = [];
|
|
32
|
+
// Phase 1: Validate ALL effects before applying any
|
|
33
|
+
const errors = this.validateAll(effects);
|
|
34
|
+
if (errors.length > 0) {
|
|
35
|
+
return { success: false, errors, applied: [] };
|
|
36
|
+
}
|
|
37
|
+
// Phase 2: Apply all effects (atomic - all or nothing)
|
|
38
|
+
for (const effect of effects) {
|
|
39
|
+
this.apply(effect);
|
|
40
|
+
}
|
|
41
|
+
// Collect emitted events to return
|
|
42
|
+
const emittedEvents = this.pendingEmittedEvents.length > 0
|
|
43
|
+
? [...this.pendingEmittedEvents]
|
|
44
|
+
: undefined;
|
|
45
|
+
this.pendingEmittedEvents = [];
|
|
46
|
+
return { success: true, errors: [], applied: effects, emittedEvents };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate all effects, returning any errors
|
|
50
|
+
*/
|
|
51
|
+
validateAll(effects) {
|
|
52
|
+
const errors = [];
|
|
53
|
+
for (const effect of effects) {
|
|
54
|
+
const error = this.validate(effect);
|
|
55
|
+
if (error) {
|
|
56
|
+
errors.push({ effect, reason: error });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return errors;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validate a single effect
|
|
63
|
+
*/
|
|
64
|
+
validate(effect) {
|
|
65
|
+
switch (effect.type) {
|
|
66
|
+
case 'score':
|
|
67
|
+
if (typeof effect.points !== 'number') {
|
|
68
|
+
return 'points must be a number';
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
case 'flag':
|
|
72
|
+
if (!effect.name || typeof effect.name !== 'string') {
|
|
73
|
+
return 'flag name required';
|
|
74
|
+
}
|
|
75
|
+
if (typeof effect.value !== 'boolean') {
|
|
76
|
+
return 'flag value must be a boolean';
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
case 'message':
|
|
80
|
+
if (!effect.id || typeof effect.id !== 'string') {
|
|
81
|
+
return 'message id required';
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case 'emit':
|
|
85
|
+
if (!effect.event || !effect.event.type) {
|
|
86
|
+
return 'emit effect requires a valid event';
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
case 'move_entity':
|
|
90
|
+
if (!effect.entityId) {
|
|
91
|
+
return 'entityId required';
|
|
92
|
+
}
|
|
93
|
+
if (!this.world.hasEntity(effect.entityId)) {
|
|
94
|
+
return `entity ${effect.entityId} not found`;
|
|
95
|
+
}
|
|
96
|
+
if (effect.destination !== null && !this.world.hasEntity(effect.destination)) {
|
|
97
|
+
return `destination ${effect.destination} not found`;
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
case 'update_entity':
|
|
101
|
+
if (!effect.entityId) {
|
|
102
|
+
return 'entityId required';
|
|
103
|
+
}
|
|
104
|
+
if (!this.world.hasEntity(effect.entityId)) {
|
|
105
|
+
return `entity ${effect.entityId} not found`;
|
|
106
|
+
}
|
|
107
|
+
break;
|
|
108
|
+
case 'set_state':
|
|
109
|
+
if (!effect.key || typeof effect.key !== 'string') {
|
|
110
|
+
return 'state key required';
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case 'update_exits':
|
|
114
|
+
if (!effect.roomId) {
|
|
115
|
+
return 'roomId required';
|
|
116
|
+
}
|
|
117
|
+
if (!this.world.hasEntity(effect.roomId)) {
|
|
118
|
+
return `room ${effect.roomId} not found`;
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
case 'unblock':
|
|
122
|
+
case 'block':
|
|
123
|
+
if (!effect.room) {
|
|
124
|
+
return 'room required';
|
|
125
|
+
}
|
|
126
|
+
if (!this.world.hasEntity(effect.room)) {
|
|
127
|
+
return `room ${effect.room} not found`;
|
|
128
|
+
}
|
|
129
|
+
if (!effect.exit) {
|
|
130
|
+
return 'exit direction required';
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case 'schedule':
|
|
134
|
+
if (!effect.daemon || typeof effect.daemon !== 'string') {
|
|
135
|
+
return 'daemon id required';
|
|
136
|
+
}
|
|
137
|
+
if (typeof effect.turns !== 'number' || effect.turns < 0) {
|
|
138
|
+
return 'turns must be a non-negative number';
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Apply a single effect
|
|
146
|
+
*/
|
|
147
|
+
apply(effect) {
|
|
148
|
+
switch (effect.type) {
|
|
149
|
+
case 'score':
|
|
150
|
+
this.applyScoreEffect(effect);
|
|
151
|
+
break;
|
|
152
|
+
case 'flag':
|
|
153
|
+
this.applyFlagEffect(effect);
|
|
154
|
+
break;
|
|
155
|
+
case 'message':
|
|
156
|
+
this.applyMessageEffect(effect);
|
|
157
|
+
break;
|
|
158
|
+
case 'emit':
|
|
159
|
+
this.applyEmitEffect(effect);
|
|
160
|
+
break;
|
|
161
|
+
case 'move_entity':
|
|
162
|
+
this.applyMoveEntityEffect(effect);
|
|
163
|
+
break;
|
|
164
|
+
case 'update_entity':
|
|
165
|
+
this.applyUpdateEntityEffect(effect);
|
|
166
|
+
break;
|
|
167
|
+
case 'set_state':
|
|
168
|
+
this.applySetStateEffect(effect);
|
|
169
|
+
break;
|
|
170
|
+
case 'update_exits':
|
|
171
|
+
this.applyUpdateExitsEffect(effect);
|
|
172
|
+
break;
|
|
173
|
+
case 'unblock':
|
|
174
|
+
// TODO: Implement when exit blocking system is in place
|
|
175
|
+
break;
|
|
176
|
+
case 'block':
|
|
177
|
+
// TODO: Implement when exit blocking system is in place
|
|
178
|
+
break;
|
|
179
|
+
case 'schedule':
|
|
180
|
+
// TODO: Implement when scheduler integration is ready
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
applyScoreEffect(effect) {
|
|
185
|
+
const scoring = this.world.getCapability('scoring');
|
|
186
|
+
if (scoring && typeof scoring.score === 'number') {
|
|
187
|
+
this.world.updateCapability('scoring', {
|
|
188
|
+
score: scoring.score + effect.points
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
applyFlagEffect(effect) {
|
|
193
|
+
this.world.setStateValue(`flag.${effect.name}`, effect.value);
|
|
194
|
+
}
|
|
195
|
+
applyMessageEffect(effect) {
|
|
196
|
+
if (this.emitEvents) {
|
|
197
|
+
const messageEvent = {
|
|
198
|
+
id: `msg-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
199
|
+
type: 'game.message',
|
|
200
|
+
timestamp: Date.now(),
|
|
201
|
+
entities: {},
|
|
202
|
+
data: {
|
|
203
|
+
messageId: effect.id,
|
|
204
|
+
...effect.data
|
|
205
|
+
},
|
|
206
|
+
narrate: true
|
|
207
|
+
};
|
|
208
|
+
this.emitEvents([messageEvent]);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
applyEmitEffect(effect) {
|
|
212
|
+
// Collect emitted events to return (instead of immediate callback)
|
|
213
|
+
this.pendingEmittedEvents.push(effect.event);
|
|
214
|
+
// Also call callback for backward compatibility
|
|
215
|
+
if (this.emitEvents) {
|
|
216
|
+
this.emitEvents([effect.event]);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
applyMoveEntityEffect(effect) {
|
|
220
|
+
this.world.moveEntity(effect.entityId, effect.destination);
|
|
221
|
+
}
|
|
222
|
+
applyUpdateEntityEffect(effect) {
|
|
223
|
+
this.world.updateEntity(effect.entityId, (entity) => {
|
|
224
|
+
for (const [key, value] of Object.entries(effect.updates)) {
|
|
225
|
+
entity[key] = value;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
applySetStateEffect(effect) {
|
|
230
|
+
this.world.setStateValue(effect.key, effect.value);
|
|
231
|
+
}
|
|
232
|
+
applyUpdateExitsEffect(effect) {
|
|
233
|
+
const room = this.world.getEntity(effect.roomId);
|
|
234
|
+
if (!room)
|
|
235
|
+
return;
|
|
236
|
+
const roomTrait = room.get(world_model_1.RoomTrait);
|
|
237
|
+
if (!roomTrait)
|
|
238
|
+
return;
|
|
239
|
+
if (!roomTrait.exits) {
|
|
240
|
+
roomTrait.exits = {};
|
|
241
|
+
}
|
|
242
|
+
// Cast exits to a mutable record for dynamic key access
|
|
243
|
+
const exits = roomTrait.exits;
|
|
244
|
+
for (const [direction, exitInfo] of Object.entries(effect.exits)) {
|
|
245
|
+
if (exitInfo === null) {
|
|
246
|
+
delete exits[direction];
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
exits[direction] = exitInfo;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.EffectProcessor = EffectProcessor;
|
|
255
|
+
//# sourceMappingURL=effect-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-processor.js","sourceRoot":"","sources":["../../src/effects/effect-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effects system for ADR-075
|
|
3
|
+
*
|
|
4
|
+
* Handlers receive read-only WorldQuery and return Effect[].
|
|
5
|
+
* EffectProcessor validates and applies effects atomically.
|
|
6
|
+
*/
|
|
7
|
+
export * from './types';
|
|
8
|
+
export { WorldQuery, createWorldQuery } from './world-query';
|
|
9
|
+
export { EffectProcessor, EventEmitCallback } from './effect-processor';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effects/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Effects system for ADR-075
|
|
4
|
+
*
|
|
5
|
+
* Handlers receive read-only WorldQuery and return Effect[].
|
|
6
|
+
* EffectProcessor validates and applies effects atomically.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.EffectProcessor = exports.createWorldQuery = void 0;
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
var world_query_1 = require("./world-query");
|
|
26
|
+
Object.defineProperty(exports, "createWorldQuery", { enumerable: true, get: function () { return world_query_1.createWorldQuery; } });
|
|
27
|
+
var effect_processor_1 = require("./effect-processor");
|
|
28
|
+
Object.defineProperty(exports, "EffectProcessor", { enumerable: true, get: function () { return effect_processor_1.EffectProcessor; } });
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/effects/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,6CAA6D;AAAxC,+GAAA,gBAAgB,OAAA;AACrC,uDAAwE;AAA/D,mHAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effect types for ADR-075: Effects-Based Handler Pattern
|
|
3
|
+
*
|
|
4
|
+
* Effects are intents, not mutations. They describe what should happen, not how.
|
|
5
|
+
* Handlers return effects, which are validated and applied by EffectProcessor.
|
|
6
|
+
*/
|
|
7
|
+
import { ISemanticEvent } from '@sharpee/core';
|
|
8
|
+
/**
|
|
9
|
+
* Effect for adding/subtracting score
|
|
10
|
+
*/
|
|
11
|
+
export interface ScoreEffect {
|
|
12
|
+
type: 'score';
|
|
13
|
+
points: number;
|
|
14
|
+
reason?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Effect for setting a world flag
|
|
18
|
+
*/
|
|
19
|
+
export interface FlagEffect {
|
|
20
|
+
type: 'flag';
|
|
21
|
+
name: string;
|
|
22
|
+
value: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Effect for emitting a message to the player
|
|
26
|
+
*/
|
|
27
|
+
export interface MessageEffect {
|
|
28
|
+
type: 'message';
|
|
29
|
+
id: string;
|
|
30
|
+
data?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Effect for emitting another semantic event
|
|
34
|
+
*/
|
|
35
|
+
export interface EmitEffect {
|
|
36
|
+
type: 'emit';
|
|
37
|
+
event: ISemanticEvent;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Effect for scheduling a daemon/fuse
|
|
41
|
+
*/
|
|
42
|
+
export interface ScheduleEffect {
|
|
43
|
+
type: 'schedule';
|
|
44
|
+
daemon: string;
|
|
45
|
+
turns: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Effect for unblocking an exit
|
|
49
|
+
*/
|
|
50
|
+
export interface UnblockEffect {
|
|
51
|
+
type: 'unblock';
|
|
52
|
+
exit: string;
|
|
53
|
+
room: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Effect for blocking an exit
|
|
57
|
+
*/
|
|
58
|
+
export interface BlockEffect {
|
|
59
|
+
type: 'block';
|
|
60
|
+
exit: string;
|
|
61
|
+
room: string;
|
|
62
|
+
reason?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Effect for moving an entity
|
|
66
|
+
*/
|
|
67
|
+
export interface MoveEntityEffect {
|
|
68
|
+
type: 'move_entity';
|
|
69
|
+
entityId: string;
|
|
70
|
+
destination: string | null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Effect for updating an entity's state
|
|
74
|
+
*/
|
|
75
|
+
export interface UpdateEntityEffect {
|
|
76
|
+
type: 'update_entity';
|
|
77
|
+
entityId: string;
|
|
78
|
+
updates: Record<string, unknown>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Effect for setting world state value
|
|
82
|
+
*/
|
|
83
|
+
export interface SetStateEffect {
|
|
84
|
+
type: 'set_state';
|
|
85
|
+
key: string;
|
|
86
|
+
value: unknown;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Effect for updating room exits
|
|
90
|
+
*/
|
|
91
|
+
export interface UpdateExitsEffect {
|
|
92
|
+
type: 'update_exits';
|
|
93
|
+
roomId: string;
|
|
94
|
+
exits: Record<string, {
|
|
95
|
+
destination: string;
|
|
96
|
+
} | null>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Union type of all effects
|
|
100
|
+
*/
|
|
101
|
+
export type Effect = ScoreEffect | FlagEffect | MessageEffect | EmitEffect | ScheduleEffect | UnblockEffect | BlockEffect | MoveEntityEffect | UpdateEntityEffect | SetStateEffect | UpdateExitsEffect;
|
|
102
|
+
/**
|
|
103
|
+
* Error from effect validation
|
|
104
|
+
*/
|
|
105
|
+
export interface EffectError {
|
|
106
|
+
effect: Effect;
|
|
107
|
+
reason: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Result of processing effects
|
|
111
|
+
*/
|
|
112
|
+
export interface EffectResult {
|
|
113
|
+
success: boolean;
|
|
114
|
+
errors: EffectError[];
|
|
115
|
+
applied: Effect[];
|
|
116
|
+
/** Events emitted via EmitEffect (for adding to turn events) */
|
|
117
|
+
emittedEvents?: ISemanticEvent[];
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/effects/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,MAAM,MAAM,GACd,WAAW,GACX,UAAU,GACV,aAAa,GACb,UAAU,GACV,cAAc,GACd,aAAa,GACb,WAAW,GACX,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,GACd,iBAAiB,CAAC;AAEtB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,aAAa,CAAC,EAAE,cAAc,EAAE,CAAC;CAClC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Effect types for ADR-075: Effects-Based Handler Pattern
|
|
4
|
+
*
|
|
5
|
+
* Effects are intents, not mutations. They describe what should happen, not how.
|
|
6
|
+
* Handlers return effects, which are validated and applied by EffectProcessor.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/effects/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorldQuery: Read-only view of WorldModel for event handlers
|
|
3
|
+
*
|
|
4
|
+
* Per ADR-075, handlers receive a read-only query interface instead of
|
|
5
|
+
* full world access. This preserves stdlib as the gatekeeper for mutations.
|
|
6
|
+
*/
|
|
7
|
+
import type { IFEntity, TraitType, ICapabilityData, IWorldModel } from '@sharpee/world-model';
|
|
8
|
+
/**
|
|
9
|
+
* Read-only query interface for handlers
|
|
10
|
+
*
|
|
11
|
+
* Allows handlers to read state to make decisions, but cannot mutate directly.
|
|
12
|
+
* Mutations happen through Effects processed by EffectProcessor.
|
|
13
|
+
*/
|
|
14
|
+
export interface WorldQuery {
|
|
15
|
+
/**
|
|
16
|
+
* Get an entity by ID
|
|
17
|
+
*/
|
|
18
|
+
getEntity(id: string): IFEntity | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Check if an entity exists
|
|
21
|
+
*/
|
|
22
|
+
hasEntity(id: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Get the player entity
|
|
25
|
+
*/
|
|
26
|
+
getPlayer(): IFEntity | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Get the room the player is in
|
|
29
|
+
*/
|
|
30
|
+
getCurrentRoom(): IFEntity | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Get the room an entity is in
|
|
33
|
+
*/
|
|
34
|
+
getContainingRoom(entityId: string): IFEntity | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Get the location (parent) of an entity
|
|
37
|
+
*/
|
|
38
|
+
getLocation(entityId: string): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Get contents of a container/room
|
|
41
|
+
*/
|
|
42
|
+
getContents(containerId: string): IFEntity[];
|
|
43
|
+
/**
|
|
44
|
+
* Find entities by trait
|
|
45
|
+
*/
|
|
46
|
+
findByTrait(traitType: TraitType): IFEntity[];
|
|
47
|
+
/**
|
|
48
|
+
* Find entities matching a predicate
|
|
49
|
+
*/
|
|
50
|
+
findWhere(predicate: (entity: IFEntity) => boolean): IFEntity[];
|
|
51
|
+
/**
|
|
52
|
+
* Get a world state value
|
|
53
|
+
*/
|
|
54
|
+
getStateValue(key: string): unknown;
|
|
55
|
+
/**
|
|
56
|
+
* Get a capability's data
|
|
57
|
+
*/
|
|
58
|
+
getCapability(name: string): ICapabilityData | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a capability exists
|
|
61
|
+
*/
|
|
62
|
+
hasCapability(name: string): boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a WorldQuery wrapper around a WorldModel
|
|
66
|
+
*
|
|
67
|
+
* This provides read-only access to the world model for event handlers.
|
|
68
|
+
*/
|
|
69
|
+
export declare function createWorldQuery(world: IWorldModel): WorldQuery;
|
|
70
|
+
//# sourceMappingURL=world-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world-query.d.ts","sourceRoot":"","sources":["../../src/effects/world-query.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE9F;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAE5C;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAE/B;;OAEG;IACH,SAAS,IAAI,QAAQ,GAAG,SAAS,CAAC;IAElC;;OAEG;IACH,cAAc,IAAI,QAAQ,GAAG,SAAS,CAAC;IAEvC;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAE1D;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAElD;;OAEG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAE7C;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,EAAE,CAAC;IAE9C;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,OAAO,GAAG,QAAQ,EAAE,CAAC;IAEhE;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAEzD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,CAkB/D"}
|