interaqt 1.1.1 → 1.1.2
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/README.md +1 -0
- package/agent/skill/interaqt-patterns.md +536 -0
- package/agent/skill/interaqt-recipes.md +501 -0
- package/agent/skill/interaqt-reference.md +409 -0
- package/package.json +2 -1
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
# interaqt API Reference
|
|
2
|
+
|
|
3
|
+
> Compact lookup for API signatures and constraints. No examples — see `interaqt-patterns.md` for usage.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Entity.create
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
Entity.create(args: {
|
|
11
|
+
name: string // PascalCase, singular, unique
|
|
12
|
+
properties: PropertyInstance[] // Array of Property.create() results
|
|
13
|
+
computation?: ComputationInstance // Transform for derived entities
|
|
14
|
+
baseEntity?: EntityInstance // For filtered entities
|
|
15
|
+
filterCondition?: MatchExp // For filtered entities
|
|
16
|
+
}): EntityInstance
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Constraints:
|
|
20
|
+
- NEVER pass `uuid` — the framework generates it
|
|
21
|
+
- `name` must match `/^[a-zA-Z0-9_]+$/`
|
|
22
|
+
- `computation` accepts only Transform (for creating derived entity collections)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Property.create
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
Property.create(args: {
|
|
30
|
+
name: string // Property name
|
|
31
|
+
type?: 'string' | 'number' | 'boolean' | 'object'
|
|
32
|
+
collection?: boolean // true for array types
|
|
33
|
+
defaultValue?: any | (() => any) // Static value or factory function
|
|
34
|
+
getValue?: (record: any) => any // Computed from same-record fields (not persisted)
|
|
35
|
+
computed?: (record: any) => any // Alias for getValue
|
|
36
|
+
computation?: ComputationInstance // Reactive: Count, WeightedSummation, Every, Any, StateMachine
|
|
37
|
+
}): PropertyInstance
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Constraints:
|
|
41
|
+
- `getValue`/`computed` are for same-record derivations only — NOT persisted
|
|
42
|
+
- `computation` results ARE persisted and auto-updated
|
|
43
|
+
- When using `computation`, ALWAYS provide `defaultValue`
|
|
44
|
+
- NEVER use Transform on Property `computation` — Transform belongs on Entity `computation`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Relation.create
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
Relation.create(args: {
|
|
52
|
+
source: EntityInstance // Source entity
|
|
53
|
+
sourceProperty: string // Navigation property on source
|
|
54
|
+
target: EntityInstance // Target entity
|
|
55
|
+
targetProperty: string // Navigation property on target
|
|
56
|
+
type: '1:1' | '1:n' | 'n:1' | 'n:n'
|
|
57
|
+
properties?: PropertyInstance[] // Relation's own properties
|
|
58
|
+
computation?: ComputationInstance // Transform for computed relations
|
|
59
|
+
}): RelationInstance
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Constraints:
|
|
63
|
+
- NEVER specify `name` — auto-generated from source+target entity names
|
|
64
|
+
- ALWAYS specify `type` explicitly
|
|
65
|
+
- Symmetric relations: set `source === target` AND `sourceProperty === targetProperty`
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Interaction.create
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
Interaction.create(args: {
|
|
73
|
+
name: string // Interaction identifier
|
|
74
|
+
action: ActionInstance // Action.create() result (identifier only)
|
|
75
|
+
payload?: PayloadInstance // Payload.create() result
|
|
76
|
+
conditions?: ConditionInstance // Execution conditions
|
|
77
|
+
}): InteractionInstance
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Action.create
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
Action.create(args: {
|
|
86
|
+
name: string // Action identifier (no logic)
|
|
87
|
+
}): ActionInstance
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Constraints:
|
|
91
|
+
- Action is ONLY an identifier — no `handler`, `execute`, or `callback`
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Payload.create / PayloadItem.create
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
Payload.create(args: {
|
|
99
|
+
items: PayloadItemInstance[]
|
|
100
|
+
}): PayloadInstance
|
|
101
|
+
|
|
102
|
+
PayloadItem.create(args: {
|
|
103
|
+
name: string // Parameter name
|
|
104
|
+
base?: EntityInstance // Entity reference for validation
|
|
105
|
+
isRef?: boolean // true = reference by ID to existing entity
|
|
106
|
+
required?: boolean // true = mandatory parameter
|
|
107
|
+
isCollection?: boolean // true = array of items
|
|
108
|
+
attributives?: AttributiveInstance // Validation rules (only works when base is set)
|
|
109
|
+
}): PayloadItemInstance
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Constraints:
|
|
113
|
+
- Without `base`: framework only checks required/collection, no concept validation
|
|
114
|
+
- With `base` + `isRef: true`: framework verifies entity exists by ID
|
|
115
|
+
- With `base` + `attributives`: framework validates data against attributive rules
|
|
116
|
+
- `attributives` are checked for EVERY item when `isCollection: true`
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Count.create
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
Count.create(args: {
|
|
124
|
+
record: EntityInstance | RelationInstance // What to count
|
|
125
|
+
direction?: 'source' | 'target' // For relation counting
|
|
126
|
+
callback?: (record: any) => boolean // Filter function
|
|
127
|
+
attributeQuery?: AttributeQueryData // Fields to load for callback
|
|
128
|
+
dataDeps?: DataDepsConfig // External data dependencies
|
|
129
|
+
}): CountInstance
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Constraints:
|
|
133
|
+
- Place on Property `computation`, not Entity `computation`
|
|
134
|
+
- ALWAYS provide `defaultValue` on the Property
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## WeightedSummation.create
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
WeightedSummation.create(args: {
|
|
142
|
+
record: RelationInstance // Relation to aggregate
|
|
143
|
+
callback: (relation: any) => { weight: number, value: number }
|
|
144
|
+
attributeQuery?: AttributeQueryData
|
|
145
|
+
dataDeps?: DataDepsConfig
|
|
146
|
+
}): WeightedSummationInstance
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Result: `sum(weight * value) / sum(weight)`
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Every.create / Any.create
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
Every.create(args: {
|
|
157
|
+
record: RelationInstance
|
|
158
|
+
callback: (relation: any) => boolean
|
|
159
|
+
attributeQuery?: AttributeQueryData
|
|
160
|
+
}): EveryInstance
|
|
161
|
+
|
|
162
|
+
Any.create(args: {
|
|
163
|
+
record: RelationInstance
|
|
164
|
+
callback: (relation: any) => boolean
|
|
165
|
+
attributeQuery?: AttributeQueryData
|
|
166
|
+
}): AnyInstance
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- `Every`: true when ALL related records satisfy callback
|
|
170
|
+
- `Any`: true when ANY related record satisfies callback
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Transform.create
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
Transform.create(args: {
|
|
178
|
+
record: EntityInstance | RelationInstance // Source data
|
|
179
|
+
callback: (record: any, dataDeps?: any) => any | null
|
|
180
|
+
attributeQuery?: AttributeQueryData
|
|
181
|
+
dataDeps?: DataDepsConfig
|
|
182
|
+
}): TransformInstance
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Constraints:
|
|
186
|
+
- Place on Entity `computation` or Relation `computation`, NEVER on Property
|
|
187
|
+
- Return `null` from callback to skip (conditional transformation)
|
|
188
|
+
- NEVER reference the entity being defined as `record` (circular reference)
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## StateMachine.create
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
StateMachine.create(args: {
|
|
196
|
+
states: StateNodeInstance[]
|
|
197
|
+
transfers: StateTransferInstance[]
|
|
198
|
+
initialState: StateNodeInstance
|
|
199
|
+
}): StateMachineInstance
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Place on Property `computation`. The property value equals the current state node's name (or its `computeValue` result).
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## StateNode.create
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
StateNode.create(args: {
|
|
210
|
+
name: string
|
|
211
|
+
computeValue?: (lastValue: any) => any // Dynamic value when entering this state
|
|
212
|
+
}): StateNodeInstance
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
- Without `computeValue`: property value is the state name string
|
|
216
|
+
- With `computeValue`: property value is the function's return value
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## StateTransfer.create
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
StateTransfer.create(args: {
|
|
224
|
+
current: StateNodeInstance // From state
|
|
225
|
+
next: StateNodeInstance // To state
|
|
226
|
+
trigger: InteractionInstance // Interaction that causes transition
|
|
227
|
+
computeTarget: (event: any) => { id: any } // Identifies which record to transition
|
|
228
|
+
}): StateTransferInstance
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`computeTarget` extracts the target entity ID from the interaction event payload.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Controller
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
new Controller(args: {
|
|
239
|
+
system: MonoSystem
|
|
240
|
+
entities: EntityInstance[]
|
|
241
|
+
relations: RelationInstance[]
|
|
242
|
+
activities: ActivityInstance[]
|
|
243
|
+
interactions: InteractionInstance[]
|
|
244
|
+
dict: DictionaryInstance[] // Global dictionaries, NOT computations
|
|
245
|
+
recordMutationSideEffects?: any[]
|
|
246
|
+
}): Controller
|
|
247
|
+
|
|
248
|
+
controller.setup(install: boolean): Promise<void>
|
|
249
|
+
controller.callInteraction(name: string, args: {
|
|
250
|
+
user: { id: string, [key: string]: any }
|
|
251
|
+
payload?: { [key: string]: any }
|
|
252
|
+
}): Promise<{ error?: { message: string, [key: string]: any }, [key: string]: any }>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Constraints:
|
|
256
|
+
- ALWAYS call `setup(true)` before any `callInteraction`
|
|
257
|
+
- `dict` is for Dictionary instances ONLY — never pass computations here
|
|
258
|
+
- `callInteraction` NEVER throws — errors are in `result.error`
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## MonoSystem
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
new MonoSystem(db: DatabaseDriver): MonoSystem
|
|
266
|
+
|
|
267
|
+
system.conceptClass = KlassByName // MUST set before creating Controller
|
|
268
|
+
system.storage // Access to storage APIs
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Database drivers: `PGLiteDB` (in-memory/testing), `PostgreSQLDB`, `SQLiteDB`, `MysqlDB`
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Storage APIs
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
system.storage.find(
|
|
279
|
+
entityName: string,
|
|
280
|
+
matchExp?: MatchExp,
|
|
281
|
+
modifier?: { limit?: number, offset?: number, orderBy?: Record<string, 'ASC'|'DESC'> },
|
|
282
|
+
attributeQuery?: AttributeQuery
|
|
283
|
+
): Promise<any[]>
|
|
284
|
+
|
|
285
|
+
system.storage.findOne(
|
|
286
|
+
entityName: string,
|
|
287
|
+
matchExp: MatchExp,
|
|
288
|
+
modifier?: any,
|
|
289
|
+
attributeQuery?: AttributeQuery
|
|
290
|
+
): Promise<any>
|
|
291
|
+
|
|
292
|
+
system.storage.create(entityName: string, data: object): Promise<any>
|
|
293
|
+
system.storage.update(entityName: string, matchExp: MatchExp, data: object): Promise<void>
|
|
294
|
+
system.storage.delete(entityName: string, matchExp: MatchExp): Promise<void>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Constraints:
|
|
298
|
+
- ALWAYS pass `attributeQuery` to `find`/`findOne` — without it, only `id` is returned
|
|
299
|
+
- Use `['*']` for all fields
|
|
300
|
+
- `create`/`update`/`delete` bypass all validation — use ONLY for test setup
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## MatchExp
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
MatchExp.atom(args: { key: string, value: [operator, value] }): MatchExp
|
|
308
|
+
|
|
309
|
+
// Operators: '=', '!=', '>', '>=', '<', '<=', 'like', 'in', 'between', 'not', 'exist'
|
|
310
|
+
|
|
311
|
+
// Chaining
|
|
312
|
+
matchExp.and(args: { key: string, value: [operator, value] }): MatchExp
|
|
313
|
+
matchExp.or(args: { key: string, value: [operator, value] }): MatchExp
|
|
314
|
+
|
|
315
|
+
// Nested field access
|
|
316
|
+
MatchExp.atom({ key: 'author.name', value: ['=', 'Alice'] })
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## AttributeQuery
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
// Simple fields
|
|
325
|
+
['id', 'name', 'email']
|
|
326
|
+
|
|
327
|
+
// All fields
|
|
328
|
+
['*']
|
|
329
|
+
|
|
330
|
+
// Nested relation data
|
|
331
|
+
['id', 'name', ['posts', { attributeQuery: ['id', 'title'] }]]
|
|
332
|
+
|
|
333
|
+
// Relation properties (the relation record itself)
|
|
334
|
+
['id', 'name', ['friends', { attributeQuery: ['id', 'name', ['&', { attributeQuery: ['since'] }]] }]]
|
|
335
|
+
|
|
336
|
+
// With filter on related data
|
|
337
|
+
['id', ['posts', {
|
|
338
|
+
attributeQuery: ['id', 'title'],
|
|
339
|
+
matchExpression: MatchExp.atom({ key: 'status', value: ['=', 'published'] })
|
|
340
|
+
}]]
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Attributive.create
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
Attributive.create(args: {
|
|
349
|
+
name: string
|
|
350
|
+
content: (record: any, eventArgs: any) => boolean
|
|
351
|
+
}): AttributiveInstance
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Used on PayloadItem `attributives` to validate referenced entities.
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## BoolExp
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
BoolExp.atom(attributive: AttributiveInstance): BoolExp
|
|
362
|
+
boolExp.and(other: BoolExp): BoolExp
|
|
363
|
+
boolExp.or(other: BoolExp): BoolExp
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Combines multiple Attributives for complex validation logic.
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Dictionary.create
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
Dictionary.create(args: {
|
|
374
|
+
name: string
|
|
375
|
+
type: 'string' | 'number' | 'boolean' | 'object'
|
|
376
|
+
collection?: boolean
|
|
377
|
+
defaultValue?: any | (() => any)
|
|
378
|
+
computation?: ComputationInstance
|
|
379
|
+
}): DictionaryInstance
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Global state values. Pass to Controller's `dict` parameter. Access via `system.storage.get('state', name)`.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Complete Exports
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
import {
|
|
390
|
+
Entity, Property, Relation,
|
|
391
|
+
Interaction, Action, Payload, PayloadItem,
|
|
392
|
+
Activity,
|
|
393
|
+
Count, Every, Any, Sum, Summation, WeightedSummation, Average,
|
|
394
|
+
Transform, StateMachine, StateNode, StateTransfer,
|
|
395
|
+
RealTime, Expression, Inequality, Equation, MathResolver,
|
|
396
|
+
Attributive, Attributives, Condition, Conditions,
|
|
397
|
+
BoolExp, MatchExp,
|
|
398
|
+
Controller, MonoSystem, Dictionary,
|
|
399
|
+
InteractionEventEntity,
|
|
400
|
+
PGLiteDB, SQLiteDB, PostgreSQLDB, MysqlDB,
|
|
401
|
+
KlassByName
|
|
402
|
+
} from 'interaqt'
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Non-existent exports (commonly mistaken):
|
|
406
|
+
- `InteractionEvent` → use `InteractionEventEntity`
|
|
407
|
+
- `FilteredEntity` → use `Entity.create` with `baseEntity` + `filterCondition`
|
|
408
|
+
- `RelationBasedEvery` → use `Every`
|
|
409
|
+
- `User`, `Post`, etc. → no pre-built entities exist
|
package/package.json
CHANGED
|
@@ -38,10 +38,11 @@
|
|
|
38
38
|
"test:core": "vitest run tests/core",
|
|
39
39
|
"test:builtins": "vitest run tests/builtins",
|
|
40
40
|
"test:coverage": "vitest run --coverage",
|
|
41
|
+
"coverage:badge": "vitest run --coverage && tsx scripts/update-coverage-badge.ts",
|
|
41
42
|
"sync:agent": "tsx scripts/sync-agent-files.ts",
|
|
42
43
|
"release": "release-it"
|
|
43
44
|
},
|
|
44
|
-
"version": "1.1.
|
|
45
|
+
"version": "1.1.2",
|
|
45
46
|
"main": "dist/index.js",
|
|
46
47
|
"files": [
|
|
47
48
|
"dist",
|