@sharpee/queries 0.9.109
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/augmentation.d.ts +46 -0
- package/augmentation.d.ts.map +1 -0
- package/augmentation.js +99 -0
- package/augmentation.js.map +1 -0
- package/entity-query.d.ts +239 -0
- package/entity-query.d.ts.map +1 -0
- package/entity-query.js +414 -0
- package/entity-query.js.map +1 -0
- package/index.d.ts +13 -0
- package/index.d.ts.map +1 -0
- package/index.js +18 -0
- package/index.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IWorldModel augmentation — adds EntityQuery entry points via declaration merging.
|
|
3
|
+
*
|
|
4
|
+
* Importing this module patches WorldModel.prototype with getter properties
|
|
5
|
+
* and methods that return EntityQuery instances. This activates the fluent
|
|
6
|
+
* query API on any WorldModel instance (including through IWorldModel references).
|
|
7
|
+
*
|
|
8
|
+
* Entry points: entities, rooms, actors, objects, scenes, regions,
|
|
9
|
+
* contents(), allContents(), having(), visible(), inScope()
|
|
10
|
+
*
|
|
11
|
+
* Owner context: @sharpee/queries (ADR-150)
|
|
12
|
+
*/
|
|
13
|
+
import { TraitType } from "../world-model/index";
|
|
14
|
+
import type { ContentsOptions } from "../if-domain/index";
|
|
15
|
+
import { EntityQuery } from './entity-query';
|
|
16
|
+
/** Query entry points added by @sharpee/queries. */
|
|
17
|
+
interface QueryEntryPoints {
|
|
18
|
+
/** Query all entities in the world. */
|
|
19
|
+
readonly all: EntityQuery;
|
|
20
|
+
/** Query all rooms. */
|
|
21
|
+
readonly rooms: EntityQuery;
|
|
22
|
+
/** Query all actors. */
|
|
23
|
+
readonly actors: EntityQuery;
|
|
24
|
+
/** Query all objects (items, containers, supporters, scenery). */
|
|
25
|
+
readonly objects: EntityQuery;
|
|
26
|
+
/** Query all scenes (ADR-149). Returns empty query if no scenes exist. */
|
|
27
|
+
readonly scenes: EntityQuery;
|
|
28
|
+
/** Query all regions (ADR-149). Returns empty query if no regions exist. */
|
|
29
|
+
readonly regions: EntityQuery;
|
|
30
|
+
/** Query contents of a specific container/room. */
|
|
31
|
+
contents(parentId: string, options?: ContentsOptions): EntityQuery;
|
|
32
|
+
/** Query all contents recursively. */
|
|
33
|
+
allContents(parentId: string, options?: ContentsOptions): EntityQuery;
|
|
34
|
+
/** Query entities with a specific trait. */
|
|
35
|
+
having(traitType: TraitType | string): EntityQuery;
|
|
36
|
+
/** Query entities visible to an observer. */
|
|
37
|
+
visible(observerId: string): EntityQuery;
|
|
38
|
+
/** Query entities in interaction scope for an observer. */
|
|
39
|
+
inScope(observerId: string): EntityQuery;
|
|
40
|
+
}
|
|
41
|
+
declare module '@sharpee/world-model' {
|
|
42
|
+
interface WorldModel extends QueryEntryPoints {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export { EntityQuery } from './entity-query';
|
|
46
|
+
//# sourceMappingURL=augmentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augmentation.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/queries/src/augmentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAiD,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA0B7C,oDAAoD;AACpD,UAAU,gBAAgB;IACxB,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAE1B,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAE5B,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAE7B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAE9B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAE7B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAE9B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,WAAW,CAAC;IAEnE,sCAAsC;IACtC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,WAAW,CAAC;IAEtE,4CAA4C;IAC5C,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;IAEnD,6CAA6C;IAC7C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAEzC,2DAA2D;IAC3D,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;CAC1C;AAED,OAAO,QAAQ,sBAAsB,CAAC;IAMpC,UAAU,UAAW,SAAQ,gBAAgB;KAAG;CACjD;AAuFD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
package/augmentation.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IWorldModel augmentation — adds EntityQuery entry points via declaration merging.
|
|
4
|
+
*
|
|
5
|
+
* Importing this module patches WorldModel.prototype with getter properties
|
|
6
|
+
* and methods that return EntityQuery instances. This activates the fluent
|
|
7
|
+
* query API on any WorldModel instance (including through IWorldModel references).
|
|
8
|
+
*
|
|
9
|
+
* Entry points: entities, rooms, actors, objects, scenes, regions,
|
|
10
|
+
* contents(), allContents(), having(), visible(), inScope()
|
|
11
|
+
*
|
|
12
|
+
* Owner context: @sharpee/queries (ADR-150)
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EntityQuery = void 0;
|
|
16
|
+
const world_model_1 = require("../world-model/index.js");
|
|
17
|
+
const entity_query_1 = require("./entity-query");
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// ADR-149 forward declarations
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Forward-declared entity type constants for Region and Scene.
|
|
23
|
+
* These match the values ADR-149 will register. Until ADR-149 is
|
|
24
|
+
* implemented, no entities of these types exist, so the corresponding
|
|
25
|
+
* entry points return empty queries.
|
|
26
|
+
*/
|
|
27
|
+
const ENTITY_TYPE_REGION = 'region';
|
|
28
|
+
const ENTITY_TYPE_SCENE = 'scene';
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Prototype patches
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
const proto = world_model_1.WorldModel.prototype;
|
|
33
|
+
// ── Readonly getters ─────────────────────────────────────────────────────
|
|
34
|
+
Object.defineProperty(proto, 'all', {
|
|
35
|
+
get() {
|
|
36
|
+
return new entity_query_1.EntityQuery(this.getAllEntities());
|
|
37
|
+
},
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(proto, 'rooms', {
|
|
42
|
+
get() {
|
|
43
|
+
return new entity_query_1.EntityQuery(this.findByType(world_model_1.EntityType.ROOM));
|
|
44
|
+
},
|
|
45
|
+
enumerable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(proto, 'actors', {
|
|
49
|
+
get() {
|
|
50
|
+
return new entity_query_1.EntityQuery(this.findByType(world_model_1.EntityType.ACTOR));
|
|
51
|
+
},
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
});
|
|
55
|
+
Object.defineProperty(proto, 'objects', {
|
|
56
|
+
get() {
|
|
57
|
+
// Objects = everything that isn't a room or actor
|
|
58
|
+
return new entity_query_1.EntityQuery(this.getAllEntities().filter((e) => e.type !== world_model_1.EntityType.ROOM
|
|
59
|
+
&& e.type !== world_model_1.EntityType.ACTOR
|
|
60
|
+
&& e.type !== ENTITY_TYPE_REGION
|
|
61
|
+
&& e.type !== ENTITY_TYPE_SCENE));
|
|
62
|
+
},
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(proto, 'scenes', {
|
|
67
|
+
get() {
|
|
68
|
+
return new entity_query_1.EntityQuery(this.findByType(ENTITY_TYPE_SCENE));
|
|
69
|
+
},
|
|
70
|
+
enumerable: true,
|
|
71
|
+
configurable: true,
|
|
72
|
+
});
|
|
73
|
+
Object.defineProperty(proto, 'regions', {
|
|
74
|
+
get() {
|
|
75
|
+
return new entity_query_1.EntityQuery(this.findByType(ENTITY_TYPE_REGION));
|
|
76
|
+
},
|
|
77
|
+
enumerable: true,
|
|
78
|
+
configurable: true,
|
|
79
|
+
});
|
|
80
|
+
// ── Methods ──────────────────────────────────────────────────────────────
|
|
81
|
+
proto.contents = function (parentId, options) {
|
|
82
|
+
return new entity_query_1.EntityQuery(this.getContents(parentId, options));
|
|
83
|
+
};
|
|
84
|
+
proto.allContents = function (parentId, options) {
|
|
85
|
+
return new entity_query_1.EntityQuery(this.getAllContents(parentId, options));
|
|
86
|
+
};
|
|
87
|
+
proto.having = function (traitType) {
|
|
88
|
+
return new entity_query_1.EntityQuery(this.findByTrait(traitType));
|
|
89
|
+
};
|
|
90
|
+
proto.visible = function (observerId) {
|
|
91
|
+
return new entity_query_1.EntityQuery(this.getVisible(observerId));
|
|
92
|
+
};
|
|
93
|
+
proto.inScope = function (observerId) {
|
|
94
|
+
return new entity_query_1.EntityQuery(this.getInScope(observerId));
|
|
95
|
+
};
|
|
96
|
+
// Re-export EntityQuery so consumers get it from the augmentation import
|
|
97
|
+
var entity_query_2 = require("./entity-query");
|
|
98
|
+
Object.defineProperty(exports, "EntityQuery", { enumerable: true, get: function () { return entity_query_2.EntityQuery; } });
|
|
99
|
+
//# sourceMappingURL=augmentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augmentation.js","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/queries/src/augmentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EntityQuery — Fluent, chainable query wrapper for IFEntity collections.
|
|
3
|
+
*
|
|
4
|
+
* Lightweight, immutable wrapper over IFEntity[] providing LINQ-style
|
|
5
|
+
* filtering, retrieval, aggregation, transformation, ordering, set
|
|
6
|
+
* operations, partitioning, grouping, and materialization methods.
|
|
7
|
+
* Each filtering method returns a new EntityQuery; the source is never mutated.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: all chainable query methods.
|
|
10
|
+
* Owner context: @sharpee/queries (ADR-150)
|
|
11
|
+
*/
|
|
12
|
+
import { IFEntity } from "../world-model/index";
|
|
13
|
+
import { TraitType } from "../world-model/index";
|
|
14
|
+
/**
|
|
15
|
+
* Fluent query wrapper for entity collections.
|
|
16
|
+
* Implements Iterable so it works with for-of loops and spread.
|
|
17
|
+
*/
|
|
18
|
+
export declare class EntityQuery implements Iterable<IFEntity> {
|
|
19
|
+
private readonly items;
|
|
20
|
+
constructor(items: IFEntity[]);
|
|
21
|
+
/**
|
|
22
|
+
* Filter entities by predicate.
|
|
23
|
+
*
|
|
24
|
+
* @param predicate - Test function applied to each entity
|
|
25
|
+
* @returns New EntityQuery containing only entities where predicate returns true
|
|
26
|
+
*/
|
|
27
|
+
where(predicate: (entity: IFEntity) => boolean): EntityQuery;
|
|
28
|
+
/**
|
|
29
|
+
* Filter to entities that have a specific trait.
|
|
30
|
+
*
|
|
31
|
+
* @param traitType - The trait type to check for
|
|
32
|
+
* @returns New EntityQuery containing only entities with the trait
|
|
33
|
+
*/
|
|
34
|
+
withTrait(traitType: TraitType | string): EntityQuery;
|
|
35
|
+
/**
|
|
36
|
+
* Filter to entities that do NOT have a specific trait.
|
|
37
|
+
*
|
|
38
|
+
* @param traitType - The trait type to exclude
|
|
39
|
+
* @returns New EntityQuery containing only entities without the trait
|
|
40
|
+
*/
|
|
41
|
+
withoutTrait(traitType: TraitType | string): EntityQuery;
|
|
42
|
+
/**
|
|
43
|
+
* Filter to entities of a specific EntityType.
|
|
44
|
+
*
|
|
45
|
+
* @param entityType - The entity type string (e.g., 'room', 'object')
|
|
46
|
+
* @returns New EntityQuery containing only entities of that type
|
|
47
|
+
*/
|
|
48
|
+
ofType(entityType: string): EntityQuery;
|
|
49
|
+
/**
|
|
50
|
+
* Filter to entities whose IdentityTrait.name matches exactly (case-sensitive).
|
|
51
|
+
* Entities without an IdentityTrait are silently excluded.
|
|
52
|
+
*
|
|
53
|
+
* @param name - The exact name to match
|
|
54
|
+
* @returns New EntityQuery containing only matching entities
|
|
55
|
+
*/
|
|
56
|
+
named(name: string): EntityQuery;
|
|
57
|
+
/**
|
|
58
|
+
* Filter to entities whose name or aliases contain the term (case-insensitive).
|
|
59
|
+
* Entities without an IdentityTrait are silently excluded.
|
|
60
|
+
*
|
|
61
|
+
* @param term - The search term (case-insensitive substring match)
|
|
62
|
+
* @returns New EntityQuery containing matching entities
|
|
63
|
+
*/
|
|
64
|
+
matching(term: string): EntityQuery;
|
|
65
|
+
/**
|
|
66
|
+
* Filter to entities that are portable (no SceneryTrait).
|
|
67
|
+
*
|
|
68
|
+
* @returns New EntityQuery containing only non-scenery entities
|
|
69
|
+
*/
|
|
70
|
+
portable(): EntityQuery;
|
|
71
|
+
/**
|
|
72
|
+
* Filter to entities visible to an observer.
|
|
73
|
+
* Delegates to the world model's visibility calculation.
|
|
74
|
+
*
|
|
75
|
+
* @param observerId - The observer entity ID
|
|
76
|
+
* @param world - The world model (needed for visibility calculation)
|
|
77
|
+
* @returns New EntityQuery containing only visible entities
|
|
78
|
+
*/
|
|
79
|
+
visibleTo(observerId: string, world: {
|
|
80
|
+
getVisible(id: string): IFEntity[];
|
|
81
|
+
}): EntityQuery;
|
|
82
|
+
/**
|
|
83
|
+
* Filter rooms to those in a region (traverses parent hierarchy).
|
|
84
|
+
* Returns empty query until ADR-149 provides RegionTrait.
|
|
85
|
+
*
|
|
86
|
+
* @param regionId - The region entity ID
|
|
87
|
+
* @param world - The world model (needed for region traversal)
|
|
88
|
+
* @returns New EntityQuery containing rooms in the region
|
|
89
|
+
*/
|
|
90
|
+
inRegion(regionId: string, world: {
|
|
91
|
+
isInRegion?(entityId: string, regionId: string): boolean;
|
|
92
|
+
}): EntityQuery;
|
|
93
|
+
/**
|
|
94
|
+
* Filter to entities located in rooms belonging to a region.
|
|
95
|
+
* Returns empty query until ADR-149 provides RegionTrait.
|
|
96
|
+
*
|
|
97
|
+
* @param regionId - The region entity ID
|
|
98
|
+
* @param world - The world model (needed for region and location lookup)
|
|
99
|
+
* @returns New EntityQuery containing entities within the region
|
|
100
|
+
*/
|
|
101
|
+
withinRegion(regionId: string, world: {
|
|
102
|
+
isInRegion?(entityId: string, regionId: string): boolean;
|
|
103
|
+
getLocation(entityId: string): string | null;
|
|
104
|
+
}): EntityQuery;
|
|
105
|
+
/**
|
|
106
|
+
* Return the first entity, or undefined if empty.
|
|
107
|
+
*/
|
|
108
|
+
first(): IFEntity | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* Return the first entity, or throw if empty.
|
|
111
|
+
*
|
|
112
|
+
* @param message - Optional error message
|
|
113
|
+
* @throws Error if the query is empty
|
|
114
|
+
*/
|
|
115
|
+
firstOrThrow(message?: string): IFEntity;
|
|
116
|
+
/**
|
|
117
|
+
* Return exactly one entity. Throws if zero or more than one.
|
|
118
|
+
*
|
|
119
|
+
* @throws Error if count is not exactly 1
|
|
120
|
+
*/
|
|
121
|
+
single(): IFEntity;
|
|
122
|
+
/**
|
|
123
|
+
* Return the last entity, or undefined if empty.
|
|
124
|
+
*/
|
|
125
|
+
last(): IFEntity | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* Return entity at index, or undefined if out of bounds.
|
|
128
|
+
*
|
|
129
|
+
* @param index - Zero-based index
|
|
130
|
+
*/
|
|
131
|
+
at(index: number): IFEntity | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* True if any entity matches the optional predicate.
|
|
134
|
+
* If no predicate, true if the query is non-empty.
|
|
135
|
+
*/
|
|
136
|
+
any(predicate?: (entity: IFEntity) => boolean): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* True if all entities match the predicate.
|
|
139
|
+
* Returns true for empty collections (vacuous truth).
|
|
140
|
+
*/
|
|
141
|
+
all(predicate: (entity: IFEntity) => boolean): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* True if no entities match the optional predicate.
|
|
144
|
+
* If no predicate, true if the query is empty.
|
|
145
|
+
*/
|
|
146
|
+
none(predicate?: (entity: IFEntity) => boolean): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Count of entities, optionally matching a predicate.
|
|
149
|
+
*/
|
|
150
|
+
count(predicate?: (entity: IFEntity) => boolean): number;
|
|
151
|
+
/**
|
|
152
|
+
* Project entities to a new form.
|
|
153
|
+
*
|
|
154
|
+
* @param selector - Transform function applied to each entity
|
|
155
|
+
* @returns Array of transformed values
|
|
156
|
+
*/
|
|
157
|
+
select<T>(selector: (entity: IFEntity) => T): T[];
|
|
158
|
+
/**
|
|
159
|
+
* Project and flatten.
|
|
160
|
+
*
|
|
161
|
+
* @param selector - Transform function returning an array per entity
|
|
162
|
+
* @returns Flattened array of all results
|
|
163
|
+
*/
|
|
164
|
+
selectMany<T>(selector: (entity: IFEntity) => T[]): T[];
|
|
165
|
+
/**
|
|
166
|
+
* Extract a specific trait from all entities (undefined for those lacking it).
|
|
167
|
+
*
|
|
168
|
+
* @param traitType - The trait type to extract
|
|
169
|
+
* @returns Array of trait instances or undefined
|
|
170
|
+
*/
|
|
171
|
+
traits<T>(traitType: TraitType | string): (T | undefined)[];
|
|
172
|
+
/**
|
|
173
|
+
* Extract a specific trait, filtering out entities that lack it.
|
|
174
|
+
*
|
|
175
|
+
* @param traitType - The trait type to extract
|
|
176
|
+
* @returns Array of trait instances (no undefined values)
|
|
177
|
+
*/
|
|
178
|
+
traitsOf<T>(traitType: TraitType | string): T[];
|
|
179
|
+
/**
|
|
180
|
+
* Sort entities by a key function.
|
|
181
|
+
*
|
|
182
|
+
* @param keyFn - Function that extracts the sort key
|
|
183
|
+
* @param direction - 'asc' (default) or 'desc'
|
|
184
|
+
* @returns New EntityQuery in sorted order
|
|
185
|
+
*/
|
|
186
|
+
orderBy<K>(keyFn: (entity: IFEntity) => K, direction?: 'asc' | 'desc'): EntityQuery;
|
|
187
|
+
/**
|
|
188
|
+
* Combine with another query (union, no duplicates by entity ID).
|
|
189
|
+
*/
|
|
190
|
+
union(other: EntityQuery): EntityQuery;
|
|
191
|
+
/**
|
|
192
|
+
* Entities present in both queries (by entity ID).
|
|
193
|
+
*/
|
|
194
|
+
intersect(other: EntityQuery): EntityQuery;
|
|
195
|
+
/**
|
|
196
|
+
* Entities in this query but not in the other (by entity ID).
|
|
197
|
+
*/
|
|
198
|
+
except(other: EntityQuery): EntityQuery;
|
|
199
|
+
/**
|
|
200
|
+
* Remove duplicate entities (by entity ID).
|
|
201
|
+
*/
|
|
202
|
+
distinct(): EntityQuery;
|
|
203
|
+
/**
|
|
204
|
+
* Skip the first N entities.
|
|
205
|
+
*/
|
|
206
|
+
skip(count: number): EntityQuery;
|
|
207
|
+
/**
|
|
208
|
+
* Take at most N entities.
|
|
209
|
+
*/
|
|
210
|
+
take(count: number): EntityQuery;
|
|
211
|
+
/**
|
|
212
|
+
* Group entities by a key function. Returns a Map of key → EntityQuery.
|
|
213
|
+
*
|
|
214
|
+
* @param keyFn - Function that extracts the group key
|
|
215
|
+
* @returns Map from group key to EntityQuery of members
|
|
216
|
+
*/
|
|
217
|
+
groupBy<K>(keyFn: (entity: IFEntity) => K): Map<K, EntityQuery>;
|
|
218
|
+
/**
|
|
219
|
+
* Return as a plain array.
|
|
220
|
+
*/
|
|
221
|
+
toArray(): IFEntity[];
|
|
222
|
+
/**
|
|
223
|
+
* Return as a Map keyed by entity ID.
|
|
224
|
+
*/
|
|
225
|
+
toMap(): Map<string, IFEntity>;
|
|
226
|
+
/**
|
|
227
|
+
* Return as a Set of entity IDs.
|
|
228
|
+
*/
|
|
229
|
+
toIdSet(): Set<string>;
|
|
230
|
+
/**
|
|
231
|
+
* Execute a side effect for each entity. Returns this for chaining.
|
|
232
|
+
*/
|
|
233
|
+
forEach(fn: (entity: IFEntity) => void): EntityQuery;
|
|
234
|
+
/**
|
|
235
|
+
* Iterable protocol — works with for-of loops and spread.
|
|
236
|
+
*/
|
|
237
|
+
[Symbol.iterator](): Iterator<IFEntity>;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=entity-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-query.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/queries/src/entity-query.ts"],"names":[],"mappings":"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"}
|
package/entity-query.js
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EntityQuery — Fluent, chainable query wrapper for IFEntity collections.
|
|
4
|
+
*
|
|
5
|
+
* Lightweight, immutable wrapper over IFEntity[] providing LINQ-style
|
|
6
|
+
* filtering, retrieval, aggregation, transformation, ordering, set
|
|
7
|
+
* operations, partitioning, grouping, and materialization methods.
|
|
8
|
+
* Each filtering method returns a new EntityQuery; the source is never mutated.
|
|
9
|
+
*
|
|
10
|
+
* Public interface: all chainable query methods.
|
|
11
|
+
* Owner context: @sharpee/queries (ADR-150)
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.EntityQuery = void 0;
|
|
15
|
+
/**
|
|
16
|
+
* Fluent query wrapper for entity collections.
|
|
17
|
+
* Implements Iterable so it works with for-of loops and spread.
|
|
18
|
+
*/
|
|
19
|
+
class EntityQuery {
|
|
20
|
+
items;
|
|
21
|
+
constructor(items) {
|
|
22
|
+
this.items = items;
|
|
23
|
+
}
|
|
24
|
+
// ── Filtering ──────────────────────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Filter entities by predicate.
|
|
27
|
+
*
|
|
28
|
+
* @param predicate - Test function applied to each entity
|
|
29
|
+
* @returns New EntityQuery containing only entities where predicate returns true
|
|
30
|
+
*/
|
|
31
|
+
where(predicate) {
|
|
32
|
+
return new EntityQuery(this.items.filter(predicate));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Filter to entities that have a specific trait.
|
|
36
|
+
*
|
|
37
|
+
* @param traitType - The trait type to check for
|
|
38
|
+
* @returns New EntityQuery containing only entities with the trait
|
|
39
|
+
*/
|
|
40
|
+
withTrait(traitType) {
|
|
41
|
+
return new EntityQuery(this.items.filter(e => e.has(traitType)));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Filter to entities that do NOT have a specific trait.
|
|
45
|
+
*
|
|
46
|
+
* @param traitType - The trait type to exclude
|
|
47
|
+
* @returns New EntityQuery containing only entities without the trait
|
|
48
|
+
*/
|
|
49
|
+
withoutTrait(traitType) {
|
|
50
|
+
return new EntityQuery(this.items.filter(e => !e.has(traitType)));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Filter to entities of a specific EntityType.
|
|
54
|
+
*
|
|
55
|
+
* @param entityType - The entity type string (e.g., 'room', 'object')
|
|
56
|
+
* @returns New EntityQuery containing only entities of that type
|
|
57
|
+
*/
|
|
58
|
+
ofType(entityType) {
|
|
59
|
+
return new EntityQuery(this.items.filter(e => e.type === entityType));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Filter to entities whose IdentityTrait.name matches exactly (case-sensitive).
|
|
63
|
+
* Entities without an IdentityTrait are silently excluded.
|
|
64
|
+
*
|
|
65
|
+
* @param name - The exact name to match
|
|
66
|
+
* @returns New EntityQuery containing only matching entities
|
|
67
|
+
*/
|
|
68
|
+
named(name) {
|
|
69
|
+
return new EntityQuery(this.items.filter(e => {
|
|
70
|
+
const identity = e.get('identity');
|
|
71
|
+
return identity && identity.name === name;
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Filter to entities whose name or aliases contain the term (case-insensitive).
|
|
76
|
+
* Entities without an IdentityTrait are silently excluded.
|
|
77
|
+
*
|
|
78
|
+
* @param term - The search term (case-insensitive substring match)
|
|
79
|
+
* @returns New EntityQuery containing matching entities
|
|
80
|
+
*/
|
|
81
|
+
matching(term) {
|
|
82
|
+
const lower = term.toLowerCase();
|
|
83
|
+
return new EntityQuery(this.items.filter(e => {
|
|
84
|
+
const identity = e.get('identity');
|
|
85
|
+
if (!identity)
|
|
86
|
+
return false;
|
|
87
|
+
if (identity.name && identity.name.toLowerCase().includes(lower))
|
|
88
|
+
return true;
|
|
89
|
+
if (identity.aliases) {
|
|
90
|
+
return identity.aliases.some(a => a.toLowerCase().includes(lower));
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Filter to entities that are portable (no SceneryTrait).
|
|
97
|
+
*
|
|
98
|
+
* @returns New EntityQuery containing only non-scenery entities
|
|
99
|
+
*/
|
|
100
|
+
portable() {
|
|
101
|
+
return new EntityQuery(this.items.filter(e => !e.has('scenery')));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Filter to entities visible to an observer.
|
|
105
|
+
* Delegates to the world model's visibility calculation.
|
|
106
|
+
*
|
|
107
|
+
* @param observerId - The observer entity ID
|
|
108
|
+
* @param world - The world model (needed for visibility calculation)
|
|
109
|
+
* @returns New EntityQuery containing only visible entities
|
|
110
|
+
*/
|
|
111
|
+
visibleTo(observerId, world) {
|
|
112
|
+
const visibleIds = new Set(world.getVisible(observerId).map(e => e.id));
|
|
113
|
+
return new EntityQuery(this.items.filter(e => visibleIds.has(e.id)));
|
|
114
|
+
}
|
|
115
|
+
// ── Spatial/Temporal Filters (ADR-149 forward) ─────────────────────────
|
|
116
|
+
/**
|
|
117
|
+
* Filter rooms to those in a region (traverses parent hierarchy).
|
|
118
|
+
* Returns empty query until ADR-149 provides RegionTrait.
|
|
119
|
+
*
|
|
120
|
+
* @param regionId - The region entity ID
|
|
121
|
+
* @param world - The world model (needed for region traversal)
|
|
122
|
+
* @returns New EntityQuery containing rooms in the region
|
|
123
|
+
*/
|
|
124
|
+
inRegion(regionId, world) {
|
|
125
|
+
if (!world.isInRegion)
|
|
126
|
+
return new EntityQuery([]);
|
|
127
|
+
return new EntityQuery(this.items.filter(e => world.isInRegion(e.id, regionId)));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Filter to entities located in rooms belonging to a region.
|
|
131
|
+
* Returns empty query until ADR-149 provides RegionTrait.
|
|
132
|
+
*
|
|
133
|
+
* @param regionId - The region entity ID
|
|
134
|
+
* @param world - The world model (needed for region and location lookup)
|
|
135
|
+
* @returns New EntityQuery containing entities within the region
|
|
136
|
+
*/
|
|
137
|
+
withinRegion(regionId, world) {
|
|
138
|
+
if (!world.isInRegion)
|
|
139
|
+
return new EntityQuery([]);
|
|
140
|
+
return new EntityQuery(this.items.filter(e => {
|
|
141
|
+
const loc = world.getLocation(e.id);
|
|
142
|
+
return loc !== null && world.isInRegion(loc, regionId);
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
// ── Retrieval ──────────────────────────────────────────────────────────
|
|
146
|
+
/**
|
|
147
|
+
* Return the first entity, or undefined if empty.
|
|
148
|
+
*/
|
|
149
|
+
first() {
|
|
150
|
+
return this.items[0];
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Return the first entity, or throw if empty.
|
|
154
|
+
*
|
|
155
|
+
* @param message - Optional error message
|
|
156
|
+
* @throws Error if the query is empty
|
|
157
|
+
*/
|
|
158
|
+
firstOrThrow(message) {
|
|
159
|
+
if (this.items.length === 0) {
|
|
160
|
+
throw new Error(message ?? 'Expected at least one entity, found none');
|
|
161
|
+
}
|
|
162
|
+
return this.items[0];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Return exactly one entity. Throws if zero or more than one.
|
|
166
|
+
*
|
|
167
|
+
* @throws Error if count is not exactly 1
|
|
168
|
+
*/
|
|
169
|
+
single() {
|
|
170
|
+
if (this.items.length === 0) {
|
|
171
|
+
throw new Error('Expected exactly one entity, found none');
|
|
172
|
+
}
|
|
173
|
+
if (this.items.length > 1) {
|
|
174
|
+
throw new Error(`Expected exactly one entity, found ${this.items.length}`);
|
|
175
|
+
}
|
|
176
|
+
return this.items[0];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Return the last entity, or undefined if empty.
|
|
180
|
+
*/
|
|
181
|
+
last() {
|
|
182
|
+
return this.items[this.items.length - 1];
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Return entity at index, or undefined if out of bounds.
|
|
186
|
+
*
|
|
187
|
+
* @param index - Zero-based index
|
|
188
|
+
*/
|
|
189
|
+
at(index) {
|
|
190
|
+
return this.items[index];
|
|
191
|
+
}
|
|
192
|
+
// ── Aggregation ────────────────────────────────────────────────────────
|
|
193
|
+
/**
|
|
194
|
+
* True if any entity matches the optional predicate.
|
|
195
|
+
* If no predicate, true if the query is non-empty.
|
|
196
|
+
*/
|
|
197
|
+
any(predicate) {
|
|
198
|
+
if (!predicate)
|
|
199
|
+
return this.items.length > 0;
|
|
200
|
+
return this.items.some(predicate);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* True if all entities match the predicate.
|
|
204
|
+
* Returns true for empty collections (vacuous truth).
|
|
205
|
+
*/
|
|
206
|
+
all(predicate) {
|
|
207
|
+
return this.items.every(predicate);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* True if no entities match the optional predicate.
|
|
211
|
+
* If no predicate, true if the query is empty.
|
|
212
|
+
*/
|
|
213
|
+
none(predicate) {
|
|
214
|
+
if (!predicate)
|
|
215
|
+
return this.items.length === 0;
|
|
216
|
+
return !this.items.some(predicate);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Count of entities, optionally matching a predicate.
|
|
220
|
+
*/
|
|
221
|
+
count(predicate) {
|
|
222
|
+
if (!predicate)
|
|
223
|
+
return this.items.length;
|
|
224
|
+
return this.items.filter(predicate).length;
|
|
225
|
+
}
|
|
226
|
+
// ── Transformation ─────────────────────────────────────────────────────
|
|
227
|
+
/**
|
|
228
|
+
* Project entities to a new form.
|
|
229
|
+
*
|
|
230
|
+
* @param selector - Transform function applied to each entity
|
|
231
|
+
* @returns Array of transformed values
|
|
232
|
+
*/
|
|
233
|
+
select(selector) {
|
|
234
|
+
return this.items.map(selector);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Project and flatten.
|
|
238
|
+
*
|
|
239
|
+
* @param selector - Transform function returning an array per entity
|
|
240
|
+
* @returns Flattened array of all results
|
|
241
|
+
*/
|
|
242
|
+
selectMany(selector) {
|
|
243
|
+
const result = [];
|
|
244
|
+
for (const item of this.items) {
|
|
245
|
+
result.push(...selector(item));
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Extract a specific trait from all entities (undefined for those lacking it).
|
|
251
|
+
*
|
|
252
|
+
* @param traitType - The trait type to extract
|
|
253
|
+
* @returns Array of trait instances or undefined
|
|
254
|
+
*/
|
|
255
|
+
traits(traitType) {
|
|
256
|
+
return this.items.map(e => e.get(traitType));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Extract a specific trait, filtering out entities that lack it.
|
|
260
|
+
*
|
|
261
|
+
* @param traitType - The trait type to extract
|
|
262
|
+
* @returns Array of trait instances (no undefined values)
|
|
263
|
+
*/
|
|
264
|
+
traitsOf(traitType) {
|
|
265
|
+
const result = [];
|
|
266
|
+
for (const item of this.items) {
|
|
267
|
+
const trait = item.get(traitType);
|
|
268
|
+
if (trait !== undefined) {
|
|
269
|
+
result.push(trait);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
// ── Ordering ───────────────────────────────────────────────────────────
|
|
275
|
+
/**
|
|
276
|
+
* Sort entities by a key function.
|
|
277
|
+
*
|
|
278
|
+
* @param keyFn - Function that extracts the sort key
|
|
279
|
+
* @param direction - 'asc' (default) or 'desc'
|
|
280
|
+
* @returns New EntityQuery in sorted order
|
|
281
|
+
*/
|
|
282
|
+
orderBy(keyFn, direction = 'asc') {
|
|
283
|
+
const sorted = [...this.items].sort((a, b) => {
|
|
284
|
+
const ka = keyFn(a);
|
|
285
|
+
const kb = keyFn(b);
|
|
286
|
+
if (ka < kb)
|
|
287
|
+
return direction === 'asc' ? -1 : 1;
|
|
288
|
+
if (ka > kb)
|
|
289
|
+
return direction === 'asc' ? 1 : -1;
|
|
290
|
+
return 0;
|
|
291
|
+
});
|
|
292
|
+
return new EntityQuery(sorted);
|
|
293
|
+
}
|
|
294
|
+
// ── Set Operations ─────────────────────────────────────────────────────
|
|
295
|
+
/**
|
|
296
|
+
* Combine with another query (union, no duplicates by entity ID).
|
|
297
|
+
*/
|
|
298
|
+
union(other) {
|
|
299
|
+
const seen = new Set(this.items.map(e => e.id));
|
|
300
|
+
const combined = [...this.items];
|
|
301
|
+
for (const item of other.items) {
|
|
302
|
+
if (!seen.has(item.id)) {
|
|
303
|
+
seen.add(item.id);
|
|
304
|
+
combined.push(item);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return new EntityQuery(combined);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Entities present in both queries (by entity ID).
|
|
311
|
+
*/
|
|
312
|
+
intersect(other) {
|
|
313
|
+
const otherIds = new Set(other.items.map(e => e.id));
|
|
314
|
+
return new EntityQuery(this.items.filter(e => otherIds.has(e.id)));
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Entities in this query but not in the other (by entity ID).
|
|
318
|
+
*/
|
|
319
|
+
except(other) {
|
|
320
|
+
const otherIds = new Set(other.items.map(e => e.id));
|
|
321
|
+
return new EntityQuery(this.items.filter(e => !otherIds.has(e.id)));
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Remove duplicate entities (by entity ID).
|
|
325
|
+
*/
|
|
326
|
+
distinct() {
|
|
327
|
+
const seen = new Set();
|
|
328
|
+
const unique = [];
|
|
329
|
+
for (const item of this.items) {
|
|
330
|
+
if (!seen.has(item.id)) {
|
|
331
|
+
seen.add(item.id);
|
|
332
|
+
unique.push(item);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return new EntityQuery(unique);
|
|
336
|
+
}
|
|
337
|
+
// ── Partitioning ───────────────────────────────────────────────────────
|
|
338
|
+
/**
|
|
339
|
+
* Skip the first N entities.
|
|
340
|
+
*/
|
|
341
|
+
skip(count) {
|
|
342
|
+
return new EntityQuery(this.items.slice(count));
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Take at most N entities.
|
|
346
|
+
*/
|
|
347
|
+
take(count) {
|
|
348
|
+
return new EntityQuery(this.items.slice(0, count));
|
|
349
|
+
}
|
|
350
|
+
// ── Grouping ───────────────────────────────────────────────────────────
|
|
351
|
+
/**
|
|
352
|
+
* Group entities by a key function. Returns a Map of key → EntityQuery.
|
|
353
|
+
*
|
|
354
|
+
* @param keyFn - Function that extracts the group key
|
|
355
|
+
* @returns Map from group key to EntityQuery of members
|
|
356
|
+
*/
|
|
357
|
+
groupBy(keyFn) {
|
|
358
|
+
const groups = new Map();
|
|
359
|
+
for (const item of this.items) {
|
|
360
|
+
const key = keyFn(item);
|
|
361
|
+
const group = groups.get(key);
|
|
362
|
+
if (group) {
|
|
363
|
+
group.push(item);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
groups.set(key, [item]);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
const result = new Map();
|
|
370
|
+
for (const [key, items] of groups) {
|
|
371
|
+
result.set(key, new EntityQuery(items));
|
|
372
|
+
}
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
// ── Materialization ────────────────────────────────────────────────────
|
|
376
|
+
/**
|
|
377
|
+
* Return as a plain array.
|
|
378
|
+
*/
|
|
379
|
+
toArray() {
|
|
380
|
+
return [...this.items];
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Return as a Map keyed by entity ID.
|
|
384
|
+
*/
|
|
385
|
+
toMap() {
|
|
386
|
+
const map = new Map();
|
|
387
|
+
for (const item of this.items) {
|
|
388
|
+
map.set(item.id, item);
|
|
389
|
+
}
|
|
390
|
+
return map;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Return as a Set of entity IDs.
|
|
394
|
+
*/
|
|
395
|
+
toIdSet() {
|
|
396
|
+
return new Set(this.items.map(e => e.id));
|
|
397
|
+
}
|
|
398
|
+
// ── Iteration ──────────────────────────────────────────────────────────
|
|
399
|
+
/**
|
|
400
|
+
* Execute a side effect for each entity. Returns this for chaining.
|
|
401
|
+
*/
|
|
402
|
+
forEach(fn) {
|
|
403
|
+
this.items.forEach(fn);
|
|
404
|
+
return new EntityQuery(this.items);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Iterable protocol — works with for-of loops and spread.
|
|
408
|
+
*/
|
|
409
|
+
[Symbol.iterator]() {
|
|
410
|
+
return this.items[Symbol.iterator]();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
exports.EntityQuery = EntityQuery;
|
|
414
|
+
//# sourceMappingURL=entity-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-query.js","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/queries/src/entity-query.ts"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sharpee/queries — Fluent entity query API (ADR-150).
|
|
3
|
+
*
|
|
4
|
+
* Provides EntityQuery, a LINQ-style chainable wrapper over IFEntity[].
|
|
5
|
+
* Importing this package activates the WorldModel augmentation, adding
|
|
6
|
+
* entry points like w.rooms, w.entities, w.contents(), etc.
|
|
7
|
+
*
|
|
8
|
+
* Public interface: EntityQuery, IWorldModel augmentation
|
|
9
|
+
* Owner context: @sharpee/queries
|
|
10
|
+
*/
|
|
11
|
+
export { EntityQuery } from './entity-query';
|
|
12
|
+
import './augmentation';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../repos/sharpee/packages/queries/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,OAAO,gBAAgB,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @sharpee/queries — Fluent entity query API (ADR-150).
|
|
4
|
+
*
|
|
5
|
+
* Provides EntityQuery, a LINQ-style chainable wrapper over IFEntity[].
|
|
6
|
+
* Importing this package activates the WorldModel augmentation, adding
|
|
7
|
+
* entry points like w.rooms, w.entities, w.contents(), etc.
|
|
8
|
+
*
|
|
9
|
+
* Public interface: EntityQuery, IWorldModel augmentation
|
|
10
|
+
* Owner context: @sharpee/queries
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.EntityQuery = void 0;
|
|
14
|
+
var entity_query_1 = require("./entity-query");
|
|
15
|
+
Object.defineProperty(exports, "EntityQuery", { enumerable: true, get: function () { return entity_query_1.EntityQuery; } });
|
|
16
|
+
// Side-effect import: patches WorldModel.prototype with query entry points
|
|
17
|
+
require("./augmentation");
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/queries/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AAEpB,2EAA2E;AAC3E,0BAAwB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sharpee/queries",
|
|
3
|
+
"version": "0.9.109",
|
|
4
|
+
"description": "LINQ-style fluent entity query API for Sharpee Interactive Fiction Platform",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"require": "./index.js",
|
|
11
|
+
"default": "./index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@sharpee/world-model": "^0.9.109",
|
|
16
|
+
"@sharpee/if-domain": "^0.9.109"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"interactive-fiction",
|
|
20
|
+
"if",
|
|
21
|
+
"text-adventure",
|
|
22
|
+
"sharpee",
|
|
23
|
+
"queries",
|
|
24
|
+
"linq"
|
|
25
|
+
],
|
|
26
|
+
"author": "Sharpee Team",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/ChicagoDave/sharpee.git",
|
|
31
|
+
"directory": "packages/queries"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|