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.
@@ -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.1",
45
+ "version": "1.1.2",
45
46
  "main": "dist/index.js",
46
47
  "files": [
47
48
  "dist",