interaqt 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/agentspace/knowledge/generator/api-reference.md +19 -21
- package/agent/agentspace/knowledge/generator/computation-implementation.md +6 -0
- package/agent/agentspace/knowledge/generator/integration-implementation-handler.md +2 -0
- package/agent/agentspace/knowledge/usage/04-reactive-computations.md +8 -0
- package/agent/agentspace/knowledge/usage/05-interactions.md +13 -0
- package/agent/agentspace/knowledge/usage/10-async-computations.md +13 -0
- package/agent/agentspace/knowledge/usage/13-testing.md +12 -2
- package/agent/agentspace/knowledge/usage/14-api-reference.md +10 -0
- package/agent/agentspace/knowledge/usage/18-api-exports-reference.md +6 -1
- package/agent/agentspace/knowledge/usage/20-postgresql-concurrency-migration.md +105 -0
- package/agent/agentspace/knowledge/usage/README.md +1 -0
- package/agent/skill/interaqt-patterns.md +41 -36
- package/agent/skill/interaqt-recipes.md +164 -108
- package/agent/skill/interaqt-reference.md +264 -75
- package/dist/core/Custom.d.ts +18 -0
- package/dist/core/Custom.d.ts.map +1 -1
- package/dist/core/EventSource.d.ts +17 -0
- package/dist/core/EventSource.d.ts.map +1 -1
- package/dist/drivers/PGLite.d.ts +2 -0
- package/dist/drivers/PGLite.d.ts.map +1 -1
- package/dist/drivers/PostgreSQL.d.ts +27 -5
- package/dist/drivers/PostgreSQL.d.ts.map +1 -1
- package/dist/drivers/SQLite.d.ts +2 -0
- package/dist/drivers/SQLite.d.ts.map +1 -1
- package/dist/index.js +3651 -3042
- package/dist/index.js.map +1 -1
- package/dist/runtime/ComputationSourceMap.d.ts.map +1 -1
- package/dist/runtime/Controller.d.ts +1 -0
- package/dist/runtime/Controller.d.ts.map +1 -1
- package/dist/runtime/MonoSystem.d.ts +2 -0
- package/dist/runtime/MonoSystem.d.ts.map +1 -1
- package/dist/runtime/Scheduler.d.ts +14 -1
- package/dist/runtime/Scheduler.d.ts.map +1 -1
- package/dist/runtime/System.d.ts +40 -6
- package/dist/runtime/System.d.ts.map +1 -1
- package/dist/runtime/computations/Any.d.ts.map +1 -1
- package/dist/runtime/computations/Average.d.ts +2 -2
- package/dist/runtime/computations/Average.d.ts.map +1 -1
- package/dist/runtime/computations/Computation.d.ts +17 -0
- package/dist/runtime/computations/Computation.d.ts.map +1 -1
- package/dist/runtime/computations/Count.d.ts +5 -1
- package/dist/runtime/computations/Count.d.ts.map +1 -1
- package/dist/runtime/computations/Every.d.ts +1 -2
- package/dist/runtime/computations/Every.d.ts.map +1 -1
- package/dist/runtime/computations/StateMachine.d.ts.map +1 -1
- package/dist/runtime/computations/Summation.d.ts +3 -1
- package/dist/runtime/computations/Summation.d.ts.map +1 -1
- package/dist/runtime/computations/Transform.d.ts.map +1 -1
- package/dist/runtime/computations/WeightedSummation.d.ts +3 -1
- package/dist/runtime/computations/WeightedSummation.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/transaction.d.ts +15 -0
- package/dist/runtime/transaction.d.ts.map +1 -0
- package/dist/storage/erstorage/EntityQueryHandle.d.ts +1 -0
- package/dist/storage/erstorage/EntityQueryHandle.d.ts.map +1 -1
- package/dist/storage/erstorage/QueryExecutor.d.ts +1 -1
- package/dist/storage/erstorage/QueryExecutor.d.ts.map +1 -1
- package/dist/storage/erstorage/RecordQueryAgent.d.ts +1 -0
- package/dist/storage/erstorage/RecordQueryAgent.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -8,18 +8,21 @@
|
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
10
|
Entity.create(args: {
|
|
11
|
-
name: string // PascalCase, singular, unique
|
|
12
|
-
properties
|
|
11
|
+
name: string // PascalCase, singular, unique, must match /^[a-zA-Z0-9_]+$/
|
|
12
|
+
properties?: PropertyInstance[] // Array of Property.create() results (defaults to [])
|
|
13
13
|
computation?: ComputationInstance // Transform for derived entities
|
|
14
|
-
baseEntity?: EntityInstance
|
|
15
|
-
|
|
14
|
+
baseEntity?: EntityInstance | RelationInstance // For filtered entities
|
|
15
|
+
matchExpression?: MatchExp // Filter condition for filtered entities
|
|
16
|
+
inputEntities?: EntityInstance[] // For merged entities
|
|
17
|
+
commonProperties?: PropertyInstance[] // Shared attributes for merged entities
|
|
16
18
|
}): EntityInstance
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
Constraints:
|
|
20
22
|
- NEVER pass `uuid` — the framework generates it
|
|
21
|
-
- `name` must match `/^[a-zA-Z0-9_]+$/`
|
|
22
23
|
- `computation` accepts only Transform (for creating derived entity collections)
|
|
24
|
+
- **Filtered entity**: set `baseEntity` + `matchExpression`
|
|
25
|
+
- **Merged entity**: set `inputEntities` + `commonProperties` (cannot define own `properties`)
|
|
23
26
|
|
|
24
27
|
---
|
|
25
28
|
|
|
@@ -27,21 +30,21 @@ Constraints:
|
|
|
27
30
|
|
|
28
31
|
```typescript
|
|
29
32
|
Property.create(args: {
|
|
30
|
-
name: string //
|
|
31
|
-
type
|
|
33
|
+
name: string // Must match /^[a-zA-Z0-9_]+$/
|
|
34
|
+
type: string // Required: 'string' | 'number' | 'boolean' | 'object'
|
|
32
35
|
collection?: boolean // true for array types
|
|
33
|
-
defaultValue?:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
computation?: ComputationInstance // Reactive: Count, WeightedSummation, Every, Any, StateMachine
|
|
36
|
+
defaultValue?: Function // Factory function returning default value
|
|
37
|
+
computed?: (record: any) => any // Computed from same-record fields (not persisted)
|
|
38
|
+
computation?: ComputationInstance // Reactive: Count, Summation, WeightedSummation, Every, Any, StateMachine, Custom
|
|
37
39
|
}): PropertyInstance
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
Constraints:
|
|
41
|
-
- `
|
|
43
|
+
- `type` is REQUIRED — always specify it
|
|
44
|
+
- `computed` is for same-record derivations only — NOT persisted
|
|
42
45
|
- `computation` results ARE persisted and auto-updated
|
|
43
|
-
- When using `computation`,
|
|
44
|
-
- NEVER use Transform on Property `computation` — Transform belongs on Entity `computation`
|
|
46
|
+
- When using `computation`, provide `defaultValue`
|
|
47
|
+
- NEVER use Transform on Property `computation` — Transform belongs on Entity/Relation `computation`
|
|
45
48
|
|
|
46
49
|
---
|
|
47
50
|
|
|
@@ -49,20 +52,33 @@ Constraints:
|
|
|
49
52
|
|
|
50
53
|
```typescript
|
|
51
54
|
Relation.create(args: {
|
|
52
|
-
|
|
55
|
+
// Base relation (all required for normal relations):
|
|
56
|
+
name?: string // Optional — auto-generated if omitted
|
|
57
|
+
source: EntityInstance | RelationInstance
|
|
53
58
|
sourceProperty: string // Navigation property on source
|
|
54
|
-
target: EntityInstance
|
|
59
|
+
target: EntityInstance | RelationInstance
|
|
55
60
|
targetProperty: string // Navigation property on target
|
|
56
61
|
type: '1:1' | '1:n' | 'n:1' | 'n:n'
|
|
57
62
|
properties?: PropertyInstance[] // Relation's own properties
|
|
58
63
|
computation?: ComputationInstance // Transform for computed relations
|
|
64
|
+
isTargetReliance?: boolean // Defaults to false
|
|
65
|
+
|
|
66
|
+
// Filtered relation:
|
|
67
|
+
baseRelation?: RelationInstance // Base relation to filter from
|
|
68
|
+
matchExpression?: MatchExp // Filter condition
|
|
69
|
+
|
|
70
|
+
// Merged relation:
|
|
71
|
+
inputRelations?: RelationInstance[] // Relations to merge (must share same source/target)
|
|
72
|
+
commonProperties?: PropertyInstance[] // Shared attributes for merged relations
|
|
59
73
|
}): RelationInstance
|
|
60
74
|
```
|
|
61
75
|
|
|
62
76
|
Constraints:
|
|
63
|
-
-
|
|
64
|
-
- ALWAYS specify `type` explicitly
|
|
77
|
+
- `name` is optional — auto-generated as `${source.name}_${sourceProperty}_${targetProperty}_${target.name}`
|
|
78
|
+
- ALWAYS specify `type` explicitly for base relations
|
|
65
79
|
- Symmetric relations: set `source === target` AND `sourceProperty === targetProperty`
|
|
80
|
+
- **Filtered relation**: requires `baseRelation` + `matchExpression` + `sourceProperty` + `targetProperty`
|
|
81
|
+
- **Merged relation**: requires `inputRelations` + `sourceProperty` + `targetProperty` (cannot specify `source`/`target`/`properties`)
|
|
66
82
|
|
|
67
83
|
---
|
|
68
84
|
|
|
@@ -73,10 +89,16 @@ Interaction.create(args: {
|
|
|
73
89
|
name: string // Interaction identifier
|
|
74
90
|
action: ActionInstance // Action.create() result (identifier only)
|
|
75
91
|
payload?: PayloadInstance // Payload.create() result
|
|
76
|
-
conditions?: ConditionInstance
|
|
92
|
+
conditions?: ConditionsInstance | ConditionInstance // Execution conditions
|
|
93
|
+
data?: EntityInstance | RelationInstance // Entity/Relation to query (for data retrieval)
|
|
94
|
+
dataPolicy?: DataPolicyInstance // Fixed data access constraints
|
|
77
95
|
}): InteractionInstance
|
|
78
96
|
```
|
|
79
97
|
|
|
98
|
+
Constraints:
|
|
99
|
+
- For data retrieval, use `GetAction` as action and specify `data`
|
|
100
|
+
- `conditions` accepts either a single `Condition` or a `Conditions` (combined with BoolExp)
|
|
101
|
+
|
|
80
102
|
---
|
|
81
103
|
|
|
82
104
|
## Action.create
|
|
@@ -89,6 +111,7 @@ Action.create(args: {
|
|
|
89
111
|
|
|
90
112
|
Constraints:
|
|
91
113
|
- Action is ONLY an identifier — no `handler`, `execute`, or `callback`
|
|
114
|
+
- Use `GetAction` (pre-built) for data retrieval interactions
|
|
92
115
|
|
|
93
116
|
---
|
|
94
117
|
|
|
@@ -101,37 +124,34 @@ Payload.create(args: {
|
|
|
101
124
|
|
|
102
125
|
PayloadItem.create(args: {
|
|
103
126
|
name: string // Parameter name
|
|
127
|
+
type: string // Required: data type
|
|
104
128
|
base?: EntityInstance // Entity reference for validation
|
|
105
129
|
isRef?: boolean // true = reference by ID to existing entity
|
|
106
130
|
required?: boolean // true = mandatory parameter
|
|
107
131
|
isCollection?: boolean // true = array of items
|
|
108
|
-
|
|
132
|
+
itemRef?: AttributiveInstance | EntityInstance // Reference to entities defined in other interactions (for Activity)
|
|
109
133
|
}): PayloadItemInstance
|
|
110
134
|
```
|
|
111
135
|
|
|
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
136
|
---
|
|
119
137
|
|
|
120
138
|
## Count.create
|
|
121
139
|
|
|
122
140
|
```typescript
|
|
123
141
|
Count.create(args: {
|
|
124
|
-
record
|
|
142
|
+
record?: EntityInstance | RelationInstance // What to count (for entity/global level)
|
|
143
|
+
property?: string // Relation property name (for property level)
|
|
125
144
|
direction?: 'source' | 'target' // For relation counting
|
|
126
145
|
callback?: (record: any) => boolean // Filter function
|
|
127
146
|
attributeQuery?: AttributeQueryData // Fields to load for callback
|
|
128
|
-
dataDeps?:
|
|
147
|
+
dataDeps?: DataDependencies // External data dependencies
|
|
129
148
|
}): CountInstance
|
|
130
149
|
```
|
|
131
150
|
|
|
132
151
|
Constraints:
|
|
133
|
-
-
|
|
134
|
-
-
|
|
152
|
+
- Use `record` for global/entity-level counting, `property` for property-level counting
|
|
153
|
+
- Place on Property `computation` or Dictionary `computation`
|
|
154
|
+
- Provide `defaultValue` on the Property when using as property computation
|
|
135
155
|
|
|
136
156
|
---
|
|
137
157
|
|
|
@@ -139,10 +159,12 @@ Constraints:
|
|
|
139
159
|
|
|
140
160
|
```typescript
|
|
141
161
|
WeightedSummation.create(args: {
|
|
142
|
-
record
|
|
143
|
-
|
|
162
|
+
record?: EntityInstance | RelationInstance // Entity/relation to aggregate (for global level)
|
|
163
|
+
property?: string // Relation property name (for property level)
|
|
164
|
+
direction?: 'source' | 'target' // For relation-based computation
|
|
165
|
+
callback: (record: any) => { weight: number, value: number }
|
|
144
166
|
attributeQuery?: AttributeQueryData
|
|
145
|
-
dataDeps?:
|
|
167
|
+
dataDeps?: DataDependencies
|
|
146
168
|
}): WeightedSummationInstance
|
|
147
169
|
```
|
|
148
170
|
|
|
@@ -150,19 +172,41 @@ Result: `sum(weight * value) / sum(weight)`
|
|
|
150
172
|
|
|
151
173
|
---
|
|
152
174
|
|
|
175
|
+
## Summation.create
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
Summation.create(args: {
|
|
179
|
+
record?: EntityInstance | RelationInstance // Entity/relation to sum (for global level)
|
|
180
|
+
property?: string // Relation property name (for property level)
|
|
181
|
+
direction?: 'source' | 'target' // For relation-based summation
|
|
182
|
+
attributeQuery: AttributeQueryData // Required: specifies field path to sum
|
|
183
|
+
}): SummationInstance
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Sums the field pointed to by the leftmost path in `attributeQuery`. Undefined/null/NaN/Infinity values are treated as 0.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
153
190
|
## Every.create / Any.create
|
|
154
191
|
|
|
155
192
|
```typescript
|
|
156
193
|
Every.create(args: {
|
|
157
|
-
record
|
|
158
|
-
|
|
194
|
+
record?: EntityInstance | RelationInstance // For global level
|
|
195
|
+
property?: string // Relation property name (for property level)
|
|
196
|
+
direction?: 'source' | 'target'
|
|
197
|
+
callback: (record: any) => boolean
|
|
159
198
|
attributeQuery?: AttributeQueryData
|
|
199
|
+
dataDeps?: DataDependencies
|
|
200
|
+
notEmpty?: boolean // Return value when collection is empty
|
|
160
201
|
}): EveryInstance
|
|
161
202
|
|
|
162
203
|
Any.create(args: {
|
|
163
|
-
record
|
|
164
|
-
|
|
204
|
+
record?: EntityInstance | RelationInstance
|
|
205
|
+
property?: string
|
|
206
|
+
direction?: 'source' | 'target'
|
|
207
|
+
callback: (record: any) => boolean
|
|
165
208
|
attributeQuery?: AttributeQueryData
|
|
209
|
+
dataDeps?: DataDependencies
|
|
166
210
|
}): AnyInstance
|
|
167
211
|
```
|
|
168
212
|
|
|
@@ -175,17 +219,33 @@ Any.create(args: {
|
|
|
175
219
|
|
|
176
220
|
```typescript
|
|
177
221
|
Transform.create(args: {
|
|
178
|
-
|
|
179
|
-
|
|
222
|
+
// Mode 1: Entity/Relation Transform
|
|
223
|
+
record?: EntityInstance | RelationInstance // Source data
|
|
180
224
|
attributeQuery?: AttributeQueryData
|
|
181
|
-
|
|
225
|
+
|
|
226
|
+
// Mode 2: Event-Driven Transform
|
|
227
|
+
eventDeps?: {
|
|
228
|
+
[key: string]: {
|
|
229
|
+
recordName: string
|
|
230
|
+
type: 'create' | 'update' | 'delete'
|
|
231
|
+
record?: Record<string, unknown>
|
|
232
|
+
oldRecord?: Record<string, unknown>
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Common
|
|
237
|
+
callback: Function // (this: Controller, record/mutationEvent) => any | any[] | null
|
|
238
|
+
dataDeps?: { [key: string]: DataDep }
|
|
182
239
|
}): TransformInstance
|
|
183
240
|
```
|
|
184
241
|
|
|
185
242
|
Constraints:
|
|
186
243
|
- Place on Entity `computation` or Relation `computation`, NEVER on Property
|
|
187
|
-
- Return `null` from callback to skip (conditional transformation)
|
|
244
|
+
- Return `null`/`undefined` from callback to skip (conditional transformation)
|
|
245
|
+
- Return array to create multiple records from one source
|
|
188
246
|
- NEVER reference the entity being defined as `record` (circular reference)
|
|
247
|
+
- Use `eventDeps` mode for interaction-based transformations (recommended)
|
|
248
|
+
- Use `record` mode for deriving entities from other entities
|
|
189
249
|
|
|
190
250
|
---
|
|
191
251
|
|
|
@@ -208,12 +268,16 @@ Place on Property `computation`. The property value equals the current state nod
|
|
|
208
268
|
```typescript
|
|
209
269
|
StateNode.create(args: {
|
|
210
270
|
name: string
|
|
211
|
-
computeValue?: (lastValue: any) => any
|
|
271
|
+
computeValue?: (this: Controller, lastValue: any, event?: any) => any
|
|
212
272
|
}): StateNodeInstance
|
|
213
273
|
```
|
|
214
274
|
|
|
215
275
|
- Without `computeValue`: property value is the state name string
|
|
216
276
|
- With `computeValue`: property value is the function's return value
|
|
277
|
+
- `lastValue`: previous property value before transition (undefined for initial state)
|
|
278
|
+
- `event`: the event record that triggered the transition (undefined during initialization)
|
|
279
|
+
- For interaction triggers: access `event.payload`, `event.user`, `event.interactionName`
|
|
280
|
+
- `this` is bound to the Controller instance — async functions can use `this.system.storage`
|
|
217
281
|
|
|
218
282
|
---
|
|
219
283
|
|
|
@@ -223,12 +287,28 @@ StateNode.create(args: {
|
|
|
223
287
|
StateTransfer.create(args: {
|
|
224
288
|
current: StateNodeInstance // From state
|
|
225
289
|
next: StateNodeInstance // To state
|
|
226
|
-
trigger:
|
|
227
|
-
computeTarget
|
|
290
|
+
trigger: RecordMutationEventPattern // Pattern to match against mutation events
|
|
291
|
+
computeTarget?: Function // Determines which records to transition
|
|
228
292
|
}): StateTransferInstance
|
|
229
293
|
```
|
|
230
294
|
|
|
231
|
-
|
|
295
|
+
**`trigger`** — a partial pattern object, NOT an Interaction instance:
|
|
296
|
+
```typescript
|
|
297
|
+
trigger: {
|
|
298
|
+
recordName: string // e.g. InteractionEventEntity.name
|
|
299
|
+
type: 'create' | 'update' | 'delete'
|
|
300
|
+
record?: Record<string, any> // deep partial match, e.g. { interactionName: myInteraction.name }
|
|
301
|
+
oldRecord?: Record<string, any>
|
|
302
|
+
keys?: string[]
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**`computeTarget`** — receives the mutation event, returns which record(s) to transition:
|
|
307
|
+
- Entity: `{ id: string }` or `{ id: string }[]`
|
|
308
|
+
- Relation: `{ source: { id: string }, target: { id: string } }`
|
|
309
|
+
- Return `undefined` to skip
|
|
310
|
+
- `this` is bound to Controller — async functions can use `this.system.storage`
|
|
311
|
+
- Required for property-level StateMachines; omit for global StateMachines
|
|
232
312
|
|
|
233
313
|
---
|
|
234
314
|
|
|
@@ -236,26 +316,34 @@ StateTransfer.create(args: {
|
|
|
236
316
|
|
|
237
317
|
```typescript
|
|
238
318
|
new Controller(args: {
|
|
239
|
-
system:
|
|
240
|
-
entities
|
|
241
|
-
relations
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
319
|
+
system: System
|
|
320
|
+
entities?: EntityInstance[]
|
|
321
|
+
relations?: RelationInstance[]
|
|
322
|
+
eventSources?: EventSourceInstance[] // Interactions, custom EventSources, etc.
|
|
323
|
+
dict?: DictionaryInstance[] // Global dictionaries
|
|
324
|
+
recordMutationSideEffects?: RecordMutationSideEffect[]
|
|
325
|
+
computations?: (new (...args: any[]) => Computation)[] // Additional computation handle classes
|
|
326
|
+
ignoreGuard?: boolean // Skip guard checks when true
|
|
327
|
+
forceThrowDispatchError?: boolean // Throw errors instead of returning them
|
|
246
328
|
}): Controller
|
|
247
329
|
|
|
248
|
-
controller.setup(install
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
330
|
+
controller.setup(install?: boolean): Promise<void>
|
|
331
|
+
|
|
332
|
+
controller.dispatch<TArgs, TResult>(
|
|
333
|
+
eventSource: EventSourceInstance<TArgs, TResult>,
|
|
334
|
+
args: TArgs
|
|
335
|
+
): Promise<DispatchResponse>
|
|
336
|
+
|
|
337
|
+
// DispatchResponse = { error?, data?, effects?, sideEffects?, context? }
|
|
253
338
|
```
|
|
254
339
|
|
|
255
340
|
Constraints:
|
|
256
|
-
- ALWAYS call `setup(true)` before any `
|
|
341
|
+
- ALWAYS call `setup(true)` before any `dispatch`
|
|
257
342
|
- `dict` is for Dictionary instances ONLY — never pass computations here
|
|
258
|
-
- `
|
|
343
|
+
- `dispatch` first parameter is the event source object reference, NOT a name string
|
|
344
|
+
- `dispatch` NEVER throws by default — errors are in `result.error`
|
|
345
|
+
- Set `forceThrowDispatchError: true` to make dispatch throw instead
|
|
346
|
+
- Controller automatically registers event source entities (e.g. `InteractionEventEntity`)
|
|
259
347
|
|
|
260
348
|
---
|
|
261
349
|
|
|
@@ -284,20 +372,29 @@ system.storage.find(
|
|
|
284
372
|
|
|
285
373
|
system.storage.findOne(
|
|
286
374
|
entityName: string,
|
|
287
|
-
matchExp
|
|
375
|
+
matchExp?: MatchExp,
|
|
288
376
|
modifier?: any,
|
|
289
377
|
attributeQuery?: AttributeQuery
|
|
290
378
|
): Promise<any>
|
|
291
379
|
|
|
292
380
|
system.storage.create(entityName: string, data: object): Promise<any>
|
|
293
|
-
system.storage.update(entityName: string, matchExp: MatchExp, data: object): Promise<
|
|
381
|
+
system.storage.update(entityName: string, matchExp: MatchExp, data: object): Promise<any>
|
|
294
382
|
system.storage.delete(entityName: string, matchExp: MatchExp): Promise<void>
|
|
383
|
+
|
|
384
|
+
// Dictionary-specific API
|
|
385
|
+
system.storage.dict.get(key: string): Promise<any>
|
|
386
|
+
system.storage.dict.set(key: string, value: any): Promise<void>
|
|
387
|
+
|
|
388
|
+
// General KV storage
|
|
389
|
+
system.storage.get(itemName: string, id: string, initialValue?: any): Promise<any>
|
|
390
|
+
system.storage.set(itemName: string, id: string, value: any): Promise<any>
|
|
295
391
|
```
|
|
296
392
|
|
|
297
393
|
Constraints:
|
|
298
394
|
- ALWAYS pass `attributeQuery` to `find`/`findOne` — without it, only `id` is returned
|
|
299
395
|
- Use `['*']` for all fields
|
|
300
396
|
- `create`/`update`/`delete` bypass all validation — use ONLY for test setup
|
|
397
|
+
- When querying relations, use dot notation for source/target: `{ key: 'source.id', value: ['=', id] }`
|
|
301
398
|
|
|
302
399
|
---
|
|
303
400
|
|
|
@@ -306,12 +403,15 @@ Constraints:
|
|
|
306
403
|
```typescript
|
|
307
404
|
MatchExp.atom(args: { key: string, value: [operator, value] }): MatchExp
|
|
308
405
|
|
|
309
|
-
// Operators: '=', '!=', '>', '>=', '<', '<=', 'like', 'in', 'between', 'not'
|
|
406
|
+
// Operators: '=', '!=', '>', '>=', '<', '<=', 'like', 'in', 'between', 'not'
|
|
310
407
|
|
|
311
408
|
// Chaining
|
|
312
409
|
matchExp.and(args: { key: string, value: [operator, value] }): MatchExp
|
|
313
410
|
matchExp.or(args: { key: string, value: [operator, value] }): MatchExp
|
|
314
411
|
|
|
412
|
+
// From object (all AND)
|
|
413
|
+
MatchExp.fromObject({ status: 'active', age: 25 }): MatchExp
|
|
414
|
+
|
|
315
415
|
// Nested field access
|
|
316
416
|
MatchExp.atom({ key: 'author.name', value: ['=', 'Alice'] })
|
|
317
417
|
```
|
|
@@ -346,24 +446,43 @@ MatchExp.atom({ key: 'author.name', value: ['=', 'Alice'] })
|
|
|
346
446
|
|
|
347
447
|
```typescript
|
|
348
448
|
Attributive.create(args: {
|
|
349
|
-
name
|
|
449
|
+
name?: string
|
|
350
450
|
content: (record: any, eventArgs: any) => boolean
|
|
351
451
|
}): AttributiveInstance
|
|
352
452
|
```
|
|
353
453
|
|
|
354
|
-
Used on
|
|
454
|
+
Used on Interaction `userAttributives` to validate user context.
|
|
355
455
|
|
|
356
456
|
---
|
|
357
457
|
|
|
358
458
|
## BoolExp
|
|
359
459
|
|
|
360
460
|
```typescript
|
|
361
|
-
BoolExp.atom(
|
|
362
|
-
boolExp.and(other: BoolExp): BoolExp
|
|
363
|
-
boolExp.or(other: BoolExp): BoolExp
|
|
461
|
+
BoolExp.atom(data: T): BoolExp
|
|
462
|
+
boolExp.and(other: BoolExp | T): BoolExp
|
|
463
|
+
boolExp.or(other: BoolExp | T): BoolExp
|
|
364
464
|
```
|
|
365
465
|
|
|
366
|
-
Combines multiple Attributives for complex
|
|
466
|
+
Combines multiple Attributives, Conditions, or other expressions for complex logic.
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Condition.create / Conditions.create
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
Condition.create(args: {
|
|
474
|
+
name?: string
|
|
475
|
+
content: (this: Controller, event: InteractionEventArgs) => Promise<boolean>
|
|
476
|
+
}): ConditionInstance
|
|
477
|
+
|
|
478
|
+
Conditions.create(args: {
|
|
479
|
+
content: BoolExp<ConditionInstance> // Combined with AND/OR logic
|
|
480
|
+
}): ConditionsInstance
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
- `content` returns `true` to allow, `false` to reject
|
|
484
|
+
- `this` is bound to Controller — can access `this.system.storage`
|
|
485
|
+
- Failed conditions return `{ error: { type: 'condition check failed' } }`
|
|
367
486
|
|
|
368
487
|
---
|
|
369
488
|
|
|
@@ -374,12 +493,53 @@ Dictionary.create(args: {
|
|
|
374
493
|
name: string
|
|
375
494
|
type: 'string' | 'number' | 'boolean' | 'object'
|
|
376
495
|
collection?: boolean
|
|
377
|
-
defaultValue?:
|
|
496
|
+
defaultValue?: Function
|
|
378
497
|
computation?: ComputationInstance
|
|
379
498
|
}): DictionaryInstance
|
|
380
499
|
```
|
|
381
500
|
|
|
382
|
-
Global state values. Pass to Controller's `dict` parameter. Access via `system.storage.get(
|
|
501
|
+
Global state values. Pass to Controller's `dict` parameter. Access via `system.storage.dict.get(name)` / `system.storage.dict.set(name, value)`.
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## EventSource.create
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
EventSource.create(args: {
|
|
509
|
+
name: string // Event source identifier
|
|
510
|
+
entity: EntityInstance // Entity to persist event records
|
|
511
|
+
guard?: (this: Controller, args: TArgs) => Promise<void>
|
|
512
|
+
mapEventData?: (args: TArgs) => Record<string, any>
|
|
513
|
+
resolve?: (this: Controller, args: TArgs) => Promise<TResult>
|
|
514
|
+
afterDispatch?: (this: Controller, args: TArgs, result: { data?: TResult }) => Promise<Record<string, unknown> | void>
|
|
515
|
+
}): EventSourceInstance
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
Custom event source for scheduled tasks, webhooks, or any non-interaction trigger. Dispatch via `controller.dispatch(eventSource, args)`.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## HardDeletionProperty.create
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
HardDeletionProperty.create(): PropertyInstance
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Creates a property named `_isDeleted_`. When its value transitions to `true` (via StateMachine), the Controller physically deletes the record. Use with `DELETED_STATE` / `NON_DELETED_STATE`.
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## RecordMutationSideEffect.create
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
RecordMutationSideEffect.create(args: {
|
|
536
|
+
name: string
|
|
537
|
+
record: { name: string } // Entity/relation name to monitor
|
|
538
|
+
content: (this: Controller, event: RecordMutationEvent) => Promise<any>
|
|
539
|
+
}): RecordMutationSideEffect
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Triggers custom logic on record mutations within dispatch context. Results available in `dispatchResult.sideEffects`.
|
|
383
543
|
|
|
384
544
|
---
|
|
385
545
|
|
|
@@ -387,23 +547,52 @@ Global state values. Pass to Controller's `dict` parameter. Access via `system.s
|
|
|
387
547
|
|
|
388
548
|
```typescript
|
|
389
549
|
import {
|
|
550
|
+
// Data model
|
|
390
551
|
Entity, Property, Relation,
|
|
391
|
-
|
|
552
|
+
|
|
553
|
+
// Event sources
|
|
554
|
+
EventSource, Interaction, Action, GetAction, Payload, PayloadItem,
|
|
392
555
|
Activity,
|
|
393
|
-
|
|
556
|
+
|
|
557
|
+
// Computations
|
|
558
|
+
Count, Every, Any, Summation, WeightedSummation, Average,
|
|
394
559
|
Transform, StateMachine, StateNode, StateTransfer,
|
|
395
|
-
RealTime,
|
|
396
|
-
|
|
560
|
+
RealTime, Custom,
|
|
561
|
+
|
|
562
|
+
// Math (for RealTime)
|
|
563
|
+
Expression, Inequality, Equation, MathResolver,
|
|
564
|
+
|
|
565
|
+
// Validation & conditions
|
|
566
|
+
Attributive, Attributives, DataAttributive, DataAttributives,
|
|
567
|
+
Condition, Conditions,
|
|
568
|
+
|
|
569
|
+
// Data policy
|
|
570
|
+
DataPolicy,
|
|
571
|
+
|
|
572
|
+
// Expressions
|
|
397
573
|
BoolExp, MatchExp,
|
|
574
|
+
|
|
575
|
+
// System
|
|
398
576
|
Controller, MonoSystem, Dictionary,
|
|
577
|
+
RecordMutationSideEffect,
|
|
578
|
+
HardDeletionProperty, HARD_DELETION_PROPERTY_NAME,
|
|
579
|
+
NON_DELETED_STATE, DELETED_STATE,
|
|
580
|
+
|
|
581
|
+
// Built-in entities
|
|
399
582
|
InteractionEventEntity,
|
|
583
|
+
|
|
584
|
+
// Drivers
|
|
400
585
|
PGLiteDB, SQLiteDB, PostgreSQLDB, MysqlDB,
|
|
586
|
+
|
|
587
|
+
// Utilities
|
|
401
588
|
KlassByName
|
|
402
589
|
} from 'interaqt'
|
|
403
590
|
```
|
|
404
591
|
|
|
405
592
|
Non-existent exports (commonly mistaken):
|
|
406
593
|
- `InteractionEvent` → use `InteractionEventEntity`
|
|
407
|
-
- `FilteredEntity` → use `Entity.create` with `baseEntity` + `
|
|
594
|
+
- `FilteredEntity` → use `Entity.create` with `baseEntity` + `matchExpression`
|
|
408
595
|
- `RelationBasedEvery` → use `Every`
|
|
596
|
+
- `Sum` → use `Summation`
|
|
597
|
+
- `callInteraction` → use `controller.dispatch(eventSource, args)`
|
|
409
598
|
- `User`, `Post`, etc. → no pre-built entities exist
|
package/dist/core/Custom.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IInstance } from './interfaces.js';
|
|
2
2
|
import { DataDep } from './Computation.js';
|
|
3
|
+
export type CustomConcurrency = 'serializable' | 'atomic-safe';
|
|
3
4
|
export interface CustomInstance extends IInstance {
|
|
4
5
|
name: string;
|
|
5
6
|
dataDeps?: {
|
|
@@ -10,8 +11,18 @@ export interface CustomInstance extends IInstance {
|
|
|
10
11
|
incrementalPatchCompute?: Function;
|
|
11
12
|
createState?: Function;
|
|
12
13
|
getInitialValue?: Function;
|
|
14
|
+
/**
|
|
15
|
+
* Runs inside the retryable transaction attempt when async task results are
|
|
16
|
+
* applied. Keep it deterministic and free of irreversible external IO.
|
|
17
|
+
*/
|
|
13
18
|
asyncReturn?: Function;
|
|
14
19
|
useLastValue?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Defaults to 'serializable'. Use 'atomic-safe' only when the custom
|
|
22
|
+
* computation's incremental path is built from framework atomic primitives or
|
|
23
|
+
* otherwise remains correct under READ COMMITTED retry boundaries.
|
|
24
|
+
*/
|
|
25
|
+
concurrency?: CustomConcurrency;
|
|
15
26
|
}
|
|
16
27
|
export interface CustomCreateArgs {
|
|
17
28
|
name: string;
|
|
@@ -25,6 +36,7 @@ export interface CustomCreateArgs {
|
|
|
25
36
|
getInitialValue?: Function;
|
|
26
37
|
asyncReturn?: Function;
|
|
27
38
|
useLastValue?: boolean;
|
|
39
|
+
concurrency?: CustomConcurrency;
|
|
28
40
|
}
|
|
29
41
|
export declare class Custom implements CustomInstance {
|
|
30
42
|
uuid: string;
|
|
@@ -43,6 +55,7 @@ export declare class Custom implements CustomInstance {
|
|
|
43
55
|
getInitialValue?: Function;
|
|
44
56
|
asyncReturn?: Function;
|
|
45
57
|
useLastValue?: boolean;
|
|
58
|
+
concurrency?: CustomConcurrency;
|
|
46
59
|
constructor(args: CustomCreateArgs, options?: {
|
|
47
60
|
uuid?: string;
|
|
48
61
|
});
|
|
@@ -95,6 +108,11 @@ export declare class Custom implements CustomInstance {
|
|
|
95
108
|
collection: false;
|
|
96
109
|
required: false;
|
|
97
110
|
};
|
|
111
|
+
concurrency: {
|
|
112
|
+
type: "string";
|
|
113
|
+
collection: false;
|
|
114
|
+
required: false;
|
|
115
|
+
};
|
|
98
116
|
};
|
|
99
117
|
static create(args: CustomCreateArgs, options?: {
|
|
100
118
|
uuid?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Custom.d.ts","sourceRoot":"","sources":["../../src/core/Custom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgC,MAAM,iBAAiB,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACtC,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IAC9B,uBAAuB,CAAC,EAAE,QAAQ,CAAC;IACnC,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Custom.d.ts","sourceRoot":"","sources":["../../src/core/Custom.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,26 @@ type CallbackThis = any;
|
|
|
4
4
|
export interface EventSourceInstance<TArgs = unknown, TResult = void> extends IInstance {
|
|
5
5
|
name: string;
|
|
6
6
|
entity: EntityInstance;
|
|
7
|
+
/**
|
|
8
|
+
* Runs inside the dispatch transaction attempt. It may be replayed when the
|
|
9
|
+
* transaction is promoted or retried, so it must be deterministic and must
|
|
10
|
+
* not perform irreversible external IO.
|
|
11
|
+
*/
|
|
7
12
|
guard?: (this: CallbackThis, args: TArgs) => Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Runs inside the dispatch transaction attempt and may be replayed on retry.
|
|
15
|
+
*/
|
|
8
16
|
mapEventData?: (args: TArgs) => Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Runs inside the dispatch transaction attempt and may be replayed on retry.
|
|
19
|
+
* External side effects should be modeled with record mutation side effects,
|
|
20
|
+
* which run after the final successful commit.
|
|
21
|
+
*/
|
|
9
22
|
resolve?: (this: CallbackThis, args: TArgs) => Promise<TResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Runs before commit inside the retryable transaction attempt. It may produce
|
|
25
|
+
* response context, but it must not perform irreversible external IO.
|
|
26
|
+
*/
|
|
10
27
|
afterDispatch?: (this: CallbackThis, args: TArgs, result: {
|
|
11
28
|
data?: TResult;
|
|
12
29
|
}) => Promise<Record<string, unknown> | void>;
|