interaqt 0.8.15 → 1.1.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.
Files changed (206) hide show
  1. package/agent/agentspace/knowledge/generator/api-reference.md +380 -81
  2. package/dist/builtins/index.d.ts +3 -0
  3. package/dist/builtins/index.d.ts.map +1 -0
  4. package/dist/builtins/init.d.ts +2 -0
  5. package/dist/builtins/init.d.ts.map +1 -0
  6. package/dist/{shared → builtins/interaction}/Action.d.ts +1 -1
  7. package/dist/builtins/interaction/Action.d.ts.map +1 -0
  8. package/dist/{shared → builtins/interaction}/Activity.d.ts +1 -1
  9. package/dist/builtins/interaction/Activity.d.ts.map +1 -0
  10. package/dist/{shared → builtins/interaction}/Attributive.d.ts +1 -2
  11. package/dist/builtins/interaction/Attributive.d.ts.map +1 -0
  12. package/dist/{shared → builtins/interaction}/Condition.d.ts +1 -1
  13. package/dist/builtins/interaction/Condition.d.ts.map +1 -0
  14. package/dist/{shared → builtins/interaction}/Conditions.d.ts +1 -2
  15. package/dist/builtins/interaction/Conditions.d.ts.map +1 -0
  16. package/dist/{shared → builtins/interaction}/Data.d.ts +1 -1
  17. package/dist/builtins/interaction/Data.d.ts.map +1 -0
  18. package/dist/{shared → builtins/interaction}/DataAttributives.d.ts +1 -2
  19. package/dist/builtins/interaction/DataAttributives.d.ts.map +1 -0
  20. package/dist/{shared → builtins/interaction}/Event.d.ts +1 -1
  21. package/dist/builtins/interaction/Event.d.ts.map +1 -0
  22. package/dist/{shared → builtins/interaction}/Gateway.d.ts +1 -1
  23. package/dist/builtins/interaction/Gateway.d.ts.map +1 -0
  24. package/dist/{shared → builtins/interaction}/Interaction.d.ts +39 -14
  25. package/dist/builtins/interaction/Interaction.d.ts.map +1 -0
  26. package/dist/{shared → builtins/interaction}/Payload.d.ts +1 -1
  27. package/dist/builtins/interaction/Payload.d.ts.map +1 -0
  28. package/dist/{shared → builtins/interaction}/PayloadItem.d.ts +1 -2
  29. package/dist/builtins/interaction/PayloadItem.d.ts.map +1 -0
  30. package/dist/builtins/interaction/User.d.ts.map +1 -0
  31. package/dist/builtins/interaction/activity/ActivityCall.d.ts +75 -0
  32. package/dist/builtins/interaction/activity/ActivityCall.d.ts.map +1 -0
  33. package/dist/builtins/interaction/activity/ActivityManager.d.ts +28 -0
  34. package/dist/builtins/interaction/activity/ActivityManager.d.ts.map +1 -0
  35. package/dist/{runtime → builtins/interaction}/errors/ActivityErrors.d.ts +1 -1
  36. package/dist/builtins/interaction/errors/ActivityErrors.d.ts.map +1 -0
  37. package/dist/{runtime → builtins/interaction}/errors/InteractionErrors.d.ts +1 -1
  38. package/dist/builtins/interaction/errors/InteractionErrors.d.ts.map +1 -0
  39. package/dist/builtins/interaction/index.d.ts +18 -0
  40. package/dist/builtins/interaction/index.d.ts.map +1 -0
  41. package/dist/core/Any.d.ts.map +1 -0
  42. package/dist/core/Average.d.ts.map +1 -0
  43. package/dist/core/BoolExp.d.ts.map +1 -0
  44. package/dist/{shared → core}/Computation.d.ts +2 -2
  45. package/dist/core/Computation.d.ts.map +1 -0
  46. package/dist/core/Count.d.ts.map +1 -0
  47. package/dist/core/Custom.d.ts.map +1 -0
  48. package/dist/core/Entity.d.ts.map +1 -0
  49. package/dist/core/EventSource.d.ts +52 -0
  50. package/dist/core/EventSource.d.ts.map +1 -0
  51. package/dist/core/Every.d.ts.map +1 -0
  52. package/dist/core/Property.d.ts.map +1 -0
  53. package/dist/core/RealDictionary.d.ts.map +1 -0
  54. package/dist/core/RealTime.d.ts.map +1 -0
  55. package/dist/core/RefContainer.d.ts.map +1 -0
  56. package/dist/core/Relation.d.ts.map +1 -0
  57. package/dist/core/SideEffect.d.ts.map +1 -0
  58. package/dist/core/StateMachine.d.ts.map +1 -0
  59. package/dist/core/StateNode.d.ts.map +1 -0
  60. package/dist/core/StateTransfer.d.ts.map +1 -0
  61. package/dist/core/Summation.d.ts.map +1 -0
  62. package/dist/core/Transform.d.ts.map +1 -0
  63. package/dist/core/WeightedSummation.d.ts.map +1 -0
  64. package/dist/{shared → core}/index.d.ts +8 -19
  65. package/dist/core/index.d.ts.map +1 -0
  66. package/dist/core/init.d.ts.map +1 -0
  67. package/dist/{shared → core}/interfaces.d.ts +0 -12
  68. package/dist/core/interfaces.d.ts.map +1 -0
  69. package/dist/{shared → core}/types.d.ts +5 -5
  70. package/dist/core/types.d.ts.map +1 -0
  71. package/dist/core/utils.d.ts.map +1 -0
  72. package/dist/drivers/Mysql.d.ts.map +1 -0
  73. package/dist/drivers/PGLite.d.ts.map +1 -0
  74. package/dist/drivers/PostgreSQL.d.ts.map +1 -0
  75. package/dist/drivers/SQLite.d.ts.map +1 -0
  76. package/dist/drivers/index.d.ts.map +1 -0
  77. package/dist/index.d.ts +2 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +5359 -5400
  80. package/dist/index.js.map +1 -1
  81. package/dist/runtime/ComputationSourceMap.d.ts.map +1 -1
  82. package/dist/runtime/Controller.d.ts +32 -14
  83. package/dist/runtime/Controller.d.ts.map +1 -1
  84. package/dist/runtime/MonoSystem.d.ts +1 -1
  85. package/dist/runtime/MonoSystem.d.ts.map +1 -1
  86. package/dist/runtime/Scheduler.d.ts +1 -1
  87. package/dist/runtime/Scheduler.d.ts.map +1 -1
  88. package/dist/runtime/System.d.ts +1 -3
  89. package/dist/runtime/System.d.ts.map +1 -1
  90. package/dist/runtime/computations/Any.d.ts +1 -1
  91. package/dist/runtime/computations/Any.d.ts.map +1 -1
  92. package/dist/runtime/computations/Average.d.ts +1 -1
  93. package/dist/runtime/computations/Average.d.ts.map +1 -1
  94. package/dist/runtime/computations/Computation.d.ts +2 -2
  95. package/dist/runtime/computations/Computation.d.ts.map +1 -1
  96. package/dist/runtime/computations/Count.d.ts +6 -2
  97. package/dist/runtime/computations/Count.d.ts.map +1 -1
  98. package/dist/runtime/computations/Custom.d.ts +1 -1
  99. package/dist/runtime/computations/Custom.d.ts.map +1 -1
  100. package/dist/runtime/computations/Every.d.ts +1 -1
  101. package/dist/runtime/computations/Every.d.ts.map +1 -1
  102. package/dist/runtime/computations/RealTime.d.ts +1 -1
  103. package/dist/runtime/computations/RealTime.d.ts.map +1 -1
  104. package/dist/runtime/computations/StateMachine.d.ts +1 -1
  105. package/dist/runtime/computations/StateMachine.d.ts.map +1 -1
  106. package/dist/runtime/computations/Summation.d.ts +1 -1
  107. package/dist/runtime/computations/Summation.d.ts.map +1 -1
  108. package/dist/runtime/computations/Transform.d.ts +1 -1
  109. package/dist/runtime/computations/Transform.d.ts.map +1 -1
  110. package/dist/runtime/computations/TransitionFinder.d.ts +1 -1
  111. package/dist/runtime/computations/TransitionFinder.d.ts.map +1 -1
  112. package/dist/runtime/computations/WeightedSummation.d.ts +1 -1
  113. package/dist/runtime/computations/WeightedSummation.d.ts.map +1 -1
  114. package/dist/runtime/errors/ConditionErrors.d.ts +5 -5
  115. package/dist/runtime/errors/ConditionErrors.d.ts.map +1 -1
  116. package/dist/runtime/errors/index.d.ts +0 -2
  117. package/dist/runtime/errors/index.d.ts.map +1 -1
  118. package/dist/runtime/index.d.ts +1 -3
  119. package/dist/runtime/index.d.ts.map +1 -1
  120. package/dist/storage/erstorage/MatchExp.d.ts +1 -1
  121. package/dist/storage/erstorage/MatchExp.d.ts.map +1 -1
  122. package/dist/storage/erstorage/MergedItemProcessor.d.ts +1 -1
  123. package/dist/storage/erstorage/MergedItemProcessor.d.ts.map +1 -1
  124. package/dist/storage/erstorage/SQLBuilder.d.ts +1 -1
  125. package/dist/storage/erstorage/SQLBuilder.d.ts.map +1 -1
  126. package/dist/storage/erstorage/Setup.d.ts +1 -1
  127. package/dist/storage/erstorage/Setup.d.ts.map +1 -1
  128. package/package.json +6 -6
  129. package/dist/dbclients/Mysql.d.ts.map +0 -1
  130. package/dist/dbclients/PGLite.d.ts.map +0 -1
  131. package/dist/dbclients/PostgreSQL.d.ts.map +0 -1
  132. package/dist/dbclients/SQLite.d.ts.map +0 -1
  133. package/dist/dbclients/index.d.ts.map +0 -1
  134. package/dist/runtime/activity/ActivityCall.d.ts +0 -67
  135. package/dist/runtime/activity/ActivityCall.d.ts.map +0 -1
  136. package/dist/runtime/activity/ActivityManager.d.ts +0 -42
  137. package/dist/runtime/activity/ActivityManager.d.ts.map +0 -1
  138. package/dist/runtime/activity/InteractionCall.d.ts +0 -92
  139. package/dist/runtime/activity/InteractionCall.d.ts.map +0 -1
  140. package/dist/runtime/errors/ActivityErrors.d.ts.map +0 -1
  141. package/dist/runtime/errors/InteractionErrors.d.ts.map +0 -1
  142. package/dist/shared/Action.d.ts.map +0 -1
  143. package/dist/shared/Activity.d.ts.map +0 -1
  144. package/dist/shared/Any.d.ts.map +0 -1
  145. package/dist/shared/Attributive.d.ts.map +0 -1
  146. package/dist/shared/Average.d.ts.map +0 -1
  147. package/dist/shared/BoolExp.d.ts.map +0 -1
  148. package/dist/shared/Computation.d.ts.map +0 -1
  149. package/dist/shared/Condition.d.ts.map +0 -1
  150. package/dist/shared/Conditions.d.ts.map +0 -1
  151. package/dist/shared/Count.d.ts.map +0 -1
  152. package/dist/shared/Custom.d.ts.map +0 -1
  153. package/dist/shared/Data.d.ts.map +0 -1
  154. package/dist/shared/DataAttributives.d.ts.map +0 -1
  155. package/dist/shared/Entity.d.ts.map +0 -1
  156. package/dist/shared/Event.d.ts.map +0 -1
  157. package/dist/shared/Every.d.ts.map +0 -1
  158. package/dist/shared/Gateway.d.ts.map +0 -1
  159. package/dist/shared/Interaction.d.ts.map +0 -1
  160. package/dist/shared/Payload.d.ts.map +0 -1
  161. package/dist/shared/PayloadItem.d.ts.map +0 -1
  162. package/dist/shared/Property.d.ts.map +0 -1
  163. package/dist/shared/RealDictionary.d.ts.map +0 -1
  164. package/dist/shared/RealTime.d.ts.map +0 -1
  165. package/dist/shared/RefContainer.d.ts.map +0 -1
  166. package/dist/shared/Relation.d.ts.map +0 -1
  167. package/dist/shared/SideEffect.d.ts.map +0 -1
  168. package/dist/shared/StateMachine.d.ts.map +0 -1
  169. package/dist/shared/StateNode.d.ts.map +0 -1
  170. package/dist/shared/StateTransfer.d.ts.map +0 -1
  171. package/dist/shared/Summation.d.ts.map +0 -1
  172. package/dist/shared/Transform.d.ts.map +0 -1
  173. package/dist/shared/User.d.ts.map +0 -1
  174. package/dist/shared/WeightedSummation.d.ts.map +0 -1
  175. package/dist/shared/index.d.ts.map +0 -1
  176. package/dist/shared/init.d.ts.map +0 -1
  177. package/dist/shared/interfaces.d.ts.map +0 -1
  178. package/dist/shared/types.d.ts.map +0 -1
  179. package/dist/shared/utils.d.ts.map +0 -1
  180. /package/dist/{shared → builtins/interaction}/User.d.ts +0 -0
  181. /package/dist/{shared → core}/Any.d.ts +0 -0
  182. /package/dist/{shared → core}/Average.d.ts +0 -0
  183. /package/dist/{shared → core}/BoolExp.d.ts +0 -0
  184. /package/dist/{shared → core}/Count.d.ts +0 -0
  185. /package/dist/{shared → core}/Custom.d.ts +0 -0
  186. /package/dist/{shared → core}/Entity.d.ts +0 -0
  187. /package/dist/{shared → core}/Every.d.ts +0 -0
  188. /package/dist/{shared → core}/Property.d.ts +0 -0
  189. /package/dist/{shared → core}/RealDictionary.d.ts +0 -0
  190. /package/dist/{shared → core}/RealTime.d.ts +0 -0
  191. /package/dist/{shared → core}/RefContainer.d.ts +0 -0
  192. /package/dist/{shared → core}/Relation.d.ts +0 -0
  193. /package/dist/{shared → core}/SideEffect.d.ts +0 -0
  194. /package/dist/{shared → core}/StateMachine.d.ts +0 -0
  195. /package/dist/{shared → core}/StateNode.d.ts +0 -0
  196. /package/dist/{shared → core}/StateTransfer.d.ts +0 -0
  197. /package/dist/{shared → core}/Summation.d.ts +0 -0
  198. /package/dist/{shared → core}/Transform.d.ts +0 -0
  199. /package/dist/{shared → core}/WeightedSummation.d.ts +0 -0
  200. /package/dist/{shared → core}/init.d.ts +0 -0
  201. /package/dist/{shared → core}/utils.d.ts +0 -0
  202. /package/dist/{dbclients → drivers}/Mysql.d.ts +0 -0
  203. /package/dist/{dbclients → drivers}/PGLite.d.ts +0 -0
  204. /package/dist/{dbclients → drivers}/PostgreSQL.d.ts +0 -0
  205. /package/dist/{dbclients → drivers}/SQLite.d.ts +0 -0
  206. /package/dist/{dbclients → drivers}/index.d.ts +0 -0
@@ -524,7 +524,151 @@ const UserProjectRelation = Relation.create({
524
524
 
525
525
  **Note**: Merged relations cannot define their own `properties` - only `commonProperties` that specify the shared attribute contract. The `source`, `target`, and `type` are inherited from input relations (which must all have the same source/target).
526
526
 
527
- ## 13.2 Computation-Related APIs
527
+ ## 13.2 EventSource API
528
+
529
+ ### EventSource.create()
530
+
531
+ Create a custom event source. EventSource is the core abstraction for all event-driven data flows in interaqt. Interactions are a built-in EventSource type; you can create custom event sources for scheduled tasks, external system callbacks, or any other trigger.
532
+
533
+ **Syntax**
534
+ ```typescript
535
+ EventSource.create<TArgs, TResult>(
536
+ config: EventSourceCreateArgs<TArgs, TResult>,
537
+ options?: { uuid?: string }
538
+ ): EventSourceInstance<TArgs, TResult>
539
+ ```
540
+
541
+ **Parameters**
542
+ - `config.name` (string, required): Event source name, used for identification and lookup
543
+ - `config.entity` (EntityInstance, required): The entity used to persist event records. Each dispatch creates a record in this entity.
544
+ - `config.guard` (function, optional): Validation function called before the event is processed. Throw an error to reject the event.
545
+ ```typescript
546
+ async function(this: Controller, args: TArgs): Promise<void>
547
+ ```
548
+ - `config.mapEventData` (function, optional): Maps event args to the data stored in the event entity record.
549
+ ```typescript
550
+ function(args: TArgs): Record<string, any>
551
+ ```
552
+ - `config.resolve` (function, optional): Resolves and returns data after the event is processed (e.g., for query events).
553
+ ```typescript
554
+ async function(this: Controller, args: TArgs): Promise<TResult>
555
+ ```
556
+ - `config.afterDispatch` (function, optional): Hook called after dispatch completes. Can return additional context.
557
+ ```typescript
558
+ async function(this: Controller, args: TArgs, result: { data?: TResult }): Promise<Record<string, unknown> | void>
559
+ ```
560
+
561
+ **EventSourceInstance Interface**
562
+ ```typescript
563
+ interface EventSourceInstance<TArgs = any, TResult = void> {
564
+ uuid: string
565
+ _type: string
566
+ name: string
567
+ entity: EntityInstance
568
+ guard?: (this: Controller, args: TArgs) => Promise<void>
569
+ mapEventData?: (args: TArgs) => Record<string, any>
570
+ resolve?: (this: Controller, args: TArgs) => Promise<TResult>
571
+ afterDispatch?: (this: Controller, args: TArgs, result: { data?: TResult }) => Promise<Record<string, unknown> | void>
572
+ }
573
+ ```
574
+
575
+ **Examples**
576
+
577
+ ```typescript
578
+ // Define event entity for storing event records
579
+ const ScheduledTaskEvent = Entity.create({
580
+ name: '_ScheduledTask_',
581
+ properties: [
582
+ Property.create({ name: 'taskName', type: 'string' }),
583
+ Property.create({ name: 'triggeredAt', type: 'number' }),
584
+ Property.create({ name: 'payload', type: 'object' })
585
+ ]
586
+ })
587
+
588
+ // Create custom event source for scheduled tasks
589
+ const scheduledTaskSource = EventSource.create({
590
+ name: 'scheduledTask',
591
+ entity: ScheduledTaskEvent,
592
+ guard: async function(this: Controller, args: { taskName: string, payload: any }) {
593
+ if (!args.taskName) {
594
+ throw new Error('Task name is required')
595
+ }
596
+ },
597
+ mapEventData: (args) => ({
598
+ taskName: args.taskName,
599
+ triggeredAt: Math.floor(Date.now() / 1000),
600
+ payload: args.payload
601
+ })
602
+ })
603
+
604
+ // Register and dispatch
605
+ const controller = new Controller({
606
+ system,
607
+ entities: [User, Post],
608
+ relations: [],
609
+ eventSources: [scheduledTaskSource],
610
+ dict: []
611
+ })
612
+
613
+ await controller.setup(true)
614
+
615
+ // Dispatch the event
616
+ const result = await controller.dispatch(scheduledTaskSource, {
617
+ taskName: 'cleanupExpiredSessions',
618
+ payload: { maxAge: 86400 }
619
+ })
620
+ ```
621
+
622
+ **Custom Event Source for External Callbacks**
623
+
624
+ ```typescript
625
+ const WebhookEvent = Entity.create({
626
+ name: '_Webhook_',
627
+ properties: [
628
+ Property.create({ name: 'source', type: 'string' }),
629
+ Property.create({ name: 'eventType', type: 'string' }),
630
+ Property.create({ name: 'data', type: 'object' })
631
+ ]
632
+ })
633
+
634
+ const webhookSource = EventSource.create({
635
+ name: 'webhook',
636
+ entity: WebhookEvent,
637
+ guard: async function(this: Controller, args: { source: string, secret: string, eventType: string, data: any }) {
638
+ const validSecret = await this.system.storage.get('config', `webhook_secret_${args.source}`)
639
+ if (args.secret !== validSecret) {
640
+ throw new Error('Invalid webhook secret')
641
+ }
642
+ },
643
+ mapEventData: (args) => ({
644
+ source: args.source,
645
+ eventType: args.eventType,
646
+ data: args.data
647
+ }),
648
+ resolve: async function(this: Controller, args) {
649
+ return { received: true, timestamp: Date.now() }
650
+ }
651
+ })
652
+
653
+ // Dispatch when webhook is received
654
+ const result = await controller.dispatch(webhookSource, {
655
+ source: 'stripe',
656
+ secret: 'whsec_xxx',
657
+ eventType: 'payment.completed',
658
+ data: { orderId: 'order_123', amount: 9900 }
659
+ })
660
+ ```
661
+
662
+ **Key Points**
663
+ 1. Every event source must have an `entity` to persist event records
664
+ 2. `guard` runs before event processing; throw to reject the event
665
+ 3. `mapEventData` converts dispatch args into the format stored in the entity
666
+ 4. `resolve` returns data to the caller (useful for query-type events)
667
+ 5. `afterDispatch` runs after successful processing and can return additional context
668
+ 6. The Controller automatically registers the event source's entity if not already in the entities list
669
+ 7. Interaction is a built-in EventSource type that provides pre-built `guard`, `mapEventData`, and `resolve` implementations
670
+
671
+ ## 13.3 Computation-Related APIs
528
672
 
529
673
  ### Count.create()
530
674
 
@@ -1891,17 +2035,16 @@ const activeUsers = Dictionary.create({
1891
2035
 
1892
2036
  **Usage in Controller**
1893
2037
 
1894
- Dictionaries are passed as the 6th parameter to Controller:
2038
+ Dictionaries are passed via the `dict` parameter to Controller:
1895
2039
 
1896
2040
  ```typescript
1897
2041
  const controller = new Controller({
1898
- system: system,
1899
- entities: entities,
1900
- relations: relations,
1901
- activities: activities,
1902
- interactions: interactions,
1903
- dict: [userCountDict, systemConfig, currentTime, activeUsers],, // Dictionaries
1904
- recordMutationSideEffects: []
2042
+ system: system,
2043
+ entities: entities,
2044
+ relations: relations,
2045
+ eventSources: [...interactions],
2046
+ dict: [userCountDict, systemConfig, currentTime, activeUsers],
2047
+ recordMutationSideEffects: []
1905
2048
  });
1906
2049
  ```
1907
2050
 
@@ -2306,11 +2449,13 @@ const bulkApproveTransfer = StateTransfer.create({
2306
2449
  });
2307
2450
  ```
2308
2451
 
2309
- ## 13.3 Interaction-Related APIs
2452
+ ## 13.4 Interaction-Related APIs
2453
+
2454
+ Interaction is a built-in EventSource type provided by interaqt. It implements `EventSourceInstance<InteractionEventArgs>` and provides pre-built guard (condition checks, user validation, payload validation), event data mapping, and data retrieval logic.
2310
2455
 
2311
2456
  ### Interaction.create()
2312
2457
 
2313
- Create user interaction definition.
2458
+ Create user interaction definition. Returns an `InteractionInstance` which implements `EventSourceInstance<InteractionEventArgs>` and can be directly passed to `controller.dispatch()`.
2314
2459
 
2315
2460
  **Syntax**
2316
2461
  ```typescript
@@ -2322,7 +2467,6 @@ Interaction.create(config: InteractionConfig): InteractionInstance
2322
2467
  - `config.action` (Action, required): Interaction action
2323
2468
  - `config.payload` (Payload, optional): Interaction parameters
2324
2469
  - `config.conditions` (Condition|Conditions, optional): Execution conditions
2325
- - `config.sideEffects` (SideEffect[], optional): Side effect handlers
2326
2470
  - `config.data` (Entity|Relation, optional): Associated data entity
2327
2471
  - `config.dataPolicy` (DataPolicy, optional): Data access policy for data fetching interactions
2328
2472
 
@@ -2410,13 +2554,13 @@ const GetPostsPaginated = Interaction.create({
2410
2554
 
2411
2555
  ```typescript
2412
2556
  // Get all users
2413
- const result = await controller.callInteraction('getAllUsers', {
2557
+ const result = await controller.dispatch(GetAllUsers, {
2414
2558
  user: { id: 'admin-user' }
2415
2559
  })
2416
2560
  // result.data contains array of users
2417
2561
 
2418
2562
  // Get filtered users with runtime query
2419
- const activeUsersResult = await controller.callInteraction('getActiveUsers', {
2563
+ const activeUsersResult = await controller.dispatch(GetActiveUsers, {
2420
2564
  user: { id: 'admin-user' },
2421
2565
  query: {
2422
2566
  match: MatchExp.atom({ key: 'status', value: ['=', 'active'] }),
@@ -2426,7 +2570,7 @@ const activeUsersResult = await controller.callInteraction('getActiveUsers', {
2426
2570
  // result.data contains filtered users with specified fields
2427
2571
 
2428
2572
  // Get user's posts
2429
- const userPostsResult = await controller.callInteraction('getUserPosts', {
2573
+ const userPostsResult = await controller.dispatch(GetUserPosts, {
2430
2574
  user: { id: 'user123' },
2431
2575
  query: {
2432
2576
  match: MatchExp.atom({ key: 'author.id', value: ['=', 'user123'] }),
@@ -2436,7 +2580,7 @@ const userPostsResult = await controller.callInteraction('getUserPosts', {
2436
2580
  // result.data contains posts authored by user123
2437
2581
 
2438
2582
  // Get paginated posts
2439
- const paginatedResult = await controller.callInteraction('getPostsPaginated', {
2583
+ const paginatedResult = await controller.dispatch(GetPostsPaginated, {
2440
2584
  user: { id: 'user123' },
2441
2585
  query: {
2442
2586
  match: MatchExp.atom({ key: 'status', value: ['=', 'published'] }),
@@ -2452,7 +2596,7 @@ const paginatedResult = await controller.callInteraction('getPostsPaginated', {
2452
2596
  1. **Required**: Must use `GetAction` as the action
2453
2597
  2. **Required**: Must specify `data` field with the Entity or Relation to query
2454
2598
  3. **Optional**: Use `dataPolicy` in Interaction definition to set fixed data access policies (match constraints, field restrictions, default sorting/pagination)
2455
- 4. **Runtime Query**: Pass `query` object in `callInteraction` to dynamically filter data at runtime (user-provided filters)
2599
+ 4. **Runtime Query**: Pass `query` object in `controller.dispatch()` to dynamically filter data at runtime (user-provided filters)
2456
2600
  5. **Conditions**: Can use conditions to control access based on query parameters
2457
2601
  6. **Response**: Retrieved data is returned in `result.data` field
2458
2602
 
@@ -2659,7 +2803,7 @@ const GetProducts = Interaction.create({
2659
2803
  })
2660
2804
 
2661
2805
  // User calls with additional filters
2662
- const result = await controller.callInteraction('getProducts', {
2806
+ const result = await controller.dispatch(GetProducts, {
2663
2807
  user: { id: 'user123' },
2664
2808
  query: {
2665
2809
  match: MatchExp.atom({ key: 'category', value: ['=', 'electronics'] }),
@@ -2747,7 +2891,7 @@ const activityItem = PayloadItem.create({
2747
2891
  })
2748
2892
  ```
2749
2893
 
2750
- ## 13.4 Activity-Related APIs
2894
+ ## 13.5 Activity-Related APIs
2751
2895
 
2752
2896
  ### Activity.create()
2753
2897
 
@@ -2979,7 +3123,7 @@ conditions: Conditions.create({
2979
3123
 
2980
3124
  **Error Handling**
2981
3125
 
2982
- When a condition fails or throws an error, the interaction call returns:
3126
+ When a condition fails or throws an error, the dispatch returns:
2983
3127
  ```typescript
2984
3128
  {
2985
3129
  error: {
@@ -2989,31 +3133,64 @@ When a condition fails or throws an error, the interaction call returns:
2989
3133
  }
2990
3134
  ```
2991
3135
 
2992
- ## 13.5 System-Related APIs
3136
+ ## 13.6 System-Related APIs
2993
3137
 
2994
3138
  ### Controller
2995
3139
 
2996
- System controller that coordinates the work of various components.
3140
+ System controller that coordinates the work of various components. All events flow through the Controller via the `dispatch()` API.
2997
3141
 
2998
3142
  **Constructor**
2999
3143
  ```typescript
3000
3144
  new Controller({
3001
3145
  system: System,
3002
- entities: EntityInstance[],
3003
- relations: RelationInstance[],
3004
- activities: ActivityInstance[],
3005
- interactions: InteractionInstance[],
3006
- dict?: DictionaryInstance[], // Note: This is for global dictionaries, NOT computations
3146
+ entities?: EntityInstance[],
3147
+ relations?: RelationInstance[],
3148
+ eventSources?: EventSourceInstance<any, any>[],
3149
+ dict?: DictionaryInstance[],
3007
3150
  recordMutationSideEffects?: RecordMutationSideEffect[],
3008
- ignorePermission?: boolean // Skip condition checks when true
3151
+ computations?: (new (...args: any[]) => Computation)[],
3152
+ ignoreGuard?: boolean, // Skip guard checks when true
3153
+ forceThrowDispatchError?: boolean // Throw errors instead of returning them
3009
3154
  })
3010
3155
  ```
3011
3156
 
3012
- ⚠️ **IMPORTANT**: Controller does NOT accept a computations parameter. All computations should be defined within the `computation` field of Entity/Relation/Property definitions. The 6th parameter `dict` is for global dictionary definitions (Dictionary.create), not for computation definitions.
3157
+ **Parameters**
3158
+ - `system` (System, required): System implementation providing storage and logging
3159
+ - `entities` (EntityInstance[], optional): Entity definitions
3160
+ - `relations` (RelationInstance[], optional): Relation definitions
3161
+ - `eventSources` (EventSourceInstance[], optional): All event sources (Interactions, custom EventSources, etc.)
3162
+ - `dict` (DictionaryInstance[], optional): Global dictionary definitions
3163
+ - `recordMutationSideEffects` (RecordMutationSideEffect[], optional): Side effects triggered on record mutations
3164
+ - `computations` ((new (...args: any[]) => Computation)[], optional): Additional computation handle classes
3165
+ - `ignoreGuard` (boolean, optional): When true, skips all guard checks on event sources
3166
+ - `forceThrowDispatchError` (boolean, optional): When true, throws errors instead of returning them in the response
3167
+
3168
+ **Note**: The Controller automatically registers event source entities (e.g., `InteractionEventEntity`) if they are not already in the entities list. You do not need to manually add them.
3169
+
3170
+ **Example**
3171
+ ```typescript
3172
+ const controller = new Controller({
3173
+ system,
3174
+ entities: [User, Post],
3175
+ relations: [UserPostRelation],
3176
+ eventSources: [
3177
+ CreatePostInteraction,
3178
+ LikePostInteraction,
3179
+ GetAllPostsInteraction,
3180
+ scheduledCleanupSource // Custom EventSource
3181
+ ],
3182
+ dict: [userCountDict, systemConfig],
3183
+ recordMutationSideEffects: [auditLogger]
3184
+ })
3185
+
3186
+ await controller.setup(true)
3187
+ ```
3188
+
3189
+ ⚠️ **IMPORTANT**: Controller does NOT accept a computations parameter for defining reactive computations. All reactive computations should be defined within the `computation` field of Entity/Relation/Property/Dictionary definitions. The `computations` parameter is only for registering additional computation handle classes.
3013
3190
 
3014
3191
  ### RecordMutationSideEffect
3015
3192
 
3016
- RecordMutationSideEffect allows you to execute custom logic when records are created, updated, or deleted within interaction contexts. It's useful for triggering external operations, logging, or custom business logic in response to data changes.
3193
+ RecordMutationSideEffect allows you to execute custom logic when records are created, updated, or deleted within dispatch contexts. It's useful for triggering external operations, logging, or custom business logic in response to data changes.
3017
3194
 
3018
3195
  **Syntax**
3019
3196
  ```typescript
@@ -3041,11 +3218,11 @@ type RecordMutationEvent = {
3041
3218
  ```
3042
3219
 
3043
3220
  **Important Notes**
3044
- - RecordMutationSideEffect **only** triggers within interaction execution context
3221
+ - RecordMutationSideEffect **only** triggers within dispatch execution context
3045
3222
  - Direct storage operations (e.g., `controller.system.storage.create()`) do **NOT** trigger side effects
3046
3223
  - All side effects registered for an entity are called on any mutation of that entity
3047
3224
  - Side effects run after the storage operation completes
3048
- - Side effect errors are captured but don't fail the interaction
3225
+ - Side effect errors are captured but don't fail the dispatch
3049
3226
 
3050
3227
  **Examples**
3051
3228
 
@@ -3105,7 +3282,7 @@ const controller = new Controller({
3105
3282
  system: system,
3106
3283
  entities: [User, Order, Product],
3107
3284
  relations: [],
3108
- interactions: [CreateUserInteraction, UpdateOrderInteraction],
3285
+ eventSources: [CreateUserInteraction, UpdateOrderInteraction],
3109
3286
  recordMutationSideEffects: [
3110
3287
  userCreatedLogger,
3111
3288
  auditLogger,
@@ -3113,8 +3290,8 @@ const controller = new Controller({
3113
3290
  ]
3114
3291
  });
3115
3292
 
3116
- // When interaction is called, side effects are triggered
3117
- const result = await controller.callInteraction('createUser', {
3293
+ // When event is dispatched, side effects are triggered
3294
+ const result = await controller.dispatch(CreateUserInteraction, {
3118
3295
  user: { id: 'admin' },
3119
3296
  payload: { name: 'John', email: 'john@example.com' }
3120
3297
  });
@@ -3150,33 +3327,36 @@ Initialize system.
3150
3327
  await controller.setup(true) // Create database tables
3151
3328
  ```
3152
3329
 
3153
- #### callInteraction(interactionName: string, args: InteractionEventArgs, activityName?: string, activityId?: string)
3154
- Call interaction or activity interaction.
3330
+ #### dispatch(eventSource, args)
3331
+ Unified dispatch API for all event source types. This is the primary way to trigger events in the system.
3155
3332
 
3156
- **Note about ignorePermission**: When `controller.ignorePermission` is set to `true`, this method will bypass all condition checks, user validation, and payload validation defined in the interaction.
3333
+ **Syntax**
3334
+ ```typescript
3335
+ async dispatch<TArgs, TResult>(
3336
+ eventSource: EventSourceInstance<TArgs, TResult>,
3337
+ args: TArgs
3338
+ ): Promise<DispatchResponse>
3339
+ ```
3157
3340
 
3158
3341
  **Parameters**
3159
- - `interactionName`: The name of the interaction to call
3160
- - `args`: The interaction event arguments containing user and payload
3161
- - `activityName` (optional): The name of the activity when calling an activity interaction
3162
- - `activityId` (optional): The ID of the activity instance when calling an activity interaction
3342
+ - `eventSource` (EventSourceInstance, required): The event source instance to dispatch (object reference, not a name string)
3343
+ - `args` (TArgs, required): Event-specific arguments. For Interactions, this is `InteractionEventArgs` containing `user`, `payload`, `context`, and optional `query`.
3344
+
3345
+ **Note about ignoreGuard**: When `controller.ignoreGuard` is set to `true`, dispatch will bypass all guard checks (conditions, user validation, payload validation) defined in the event source.
3163
3346
 
3164
3347
  **Return Type**
3165
3348
  ```typescript
3166
- type InteractionCallResponse = {
3167
- // Contains error information if the interaction failed
3349
+ type DispatchResponse = {
3350
+ // Contains error information if the dispatch failed
3168
3351
  error?: unknown
3169
3352
 
3170
- // For GET interactions: contains the retrieved data
3353
+ // For events with resolve: contains the resolved data
3171
3354
  data?: unknown
3172
3355
 
3173
- // The interaction event that was processed
3174
- event?: InteractionEvent
3175
-
3176
3356
  // Record mutations (create/update/delete) that occurred
3177
3357
  effects?: RecordMutationEvent[]
3178
3358
 
3179
- // Results from side effects defined in the interaction
3359
+ // Results from registered RecordMutationSideEffects
3180
3360
  sideEffects?: {
3181
3361
  [effectName: string]: {
3182
3362
  result?: unknown
@@ -3184,23 +3364,34 @@ type InteractionCallResponse = {
3184
3364
  }
3185
3365
  }
3186
3366
 
3187
- // Additional context (e.g., activityId for activity interactions)
3367
+ // Additional context from afterDispatch hook
3188
3368
  context?: {
3189
3369
  [key: string]: unknown
3190
3370
  }
3191
3371
  }
3192
3372
  ```
3193
3373
 
3194
- **Example - Regular Interaction**
3374
+ **Dispatch Flow**
3375
+ 1. Begin transaction
3376
+ 2. Execute `guard` (if provided and `ignoreGuard` is false)
3377
+ 3. Map event data via `mapEventData` and create event record
3378
+ 4. Execute `resolve` (if provided) - returns data
3379
+ 5. Execute `afterDispatch` (if provided) - returns context
3380
+ 6. Commit transaction
3381
+ 7. Run RecordMutationSideEffects
3382
+
3383
+ **Example - Dispatch Interaction**
3195
3384
  ```typescript
3196
- const result = await controller.callInteraction('createPost', {
3385
+ const result = await controller.dispatch(CreatePostInteraction, {
3197
3386
  user: { id: 'user1' },
3198
- payload: { postData: { title: 'Hello', content: 'World' } }
3387
+ payload: { postData: { title: 'Hello', content: 'World' } },
3388
+ // Optional context (e.g. for agent tools)
3389
+ context: { source: 'agent', tool: 'create_post', timestamp: Date.now() }
3199
3390
  })
3200
3391
 
3201
3392
  // Check for errors
3202
3393
  if (result.error) {
3203
- console.error('Interaction failed:', result.error)
3394
+ console.error('Dispatch failed:', result.error)
3204
3395
  return
3205
3396
  }
3206
3397
 
@@ -3213,14 +3404,40 @@ if (result.sideEffects?.emailNotification?.error) {
3213
3404
  }
3214
3405
  ```
3215
3406
 
3216
- **Example - Activity Interaction**
3407
+ **Example - Dispatch Custom EventSource**
3217
3408
  ```typescript
3218
- const result = await controller.callInteraction(
3219
- 'confirmOrder',
3220
- { user: { id: 'user1' }, payload: { orderData: {...} } },
3221
- 'OrderProcess',
3222
- 'activity-instance-1'
3223
- )
3409
+ const result = await controller.dispatch(scheduledTaskSource, {
3410
+ taskName: 'dailyReport',
3411
+ payload: { date: '2024-01-15' }
3412
+ })
3413
+ ```
3414
+
3415
+ **Example - Dispatch Get Interaction**
3416
+ ```typescript
3417
+ const result = await controller.dispatch(GetAllPostsInteraction, {
3418
+ user: { id: 'user1' },
3419
+ query: {
3420
+ match: MatchExp.atom({ key: 'status', value: ['=', 'published'] }),
3421
+ attributeQuery: ['id', 'title', 'content', 'createdAt']
3422
+ }
3423
+ })
3424
+ // result.data contains the queried records
3425
+ ```
3426
+
3427
+ #### findEventSourceByName(name)
3428
+ Find a registered event source by its name.
3429
+
3430
+ **Syntax**
3431
+ ```typescript
3432
+ findEventSourceByName(name: string): EventSourceInstance | undefined
3433
+ ```
3434
+
3435
+ **Example**
3436
+ ```typescript
3437
+ const source = controller.findEventSourceByName('createPost')
3438
+ if (source) {
3439
+ await controller.dispatch(source, { user: { id: 'user1' }, payload: {...} })
3440
+ }
3224
3441
  ```
3225
3442
 
3226
3443
  ### System
@@ -3838,7 +4055,7 @@ type ModifierData = {
3838
4055
  }
3839
4056
  ```
3840
4057
 
3841
- ## 13.6 Utility Function APIs
4058
+ ## 13.7 Utility Function APIs
3842
4059
 
3843
4060
  ### MatchExp
3844
4061
 
@@ -3924,7 +4141,7 @@ const expr2 = BoolExp.atom({ condition: 'isAdmin' })
3924
4141
  const combined = expr1.and(expr2).or({ condition: 'isOwner' })
3925
4142
  ```
3926
4143
 
3927
- ## 13.5 Query APIs
4144
+ ## 13.8 Query APIs
3928
4145
 
3929
4146
  ### Conditions
3930
4147
 
@@ -3988,11 +4205,38 @@ const combined = expr1.and(expr2).or({ condition: 'isOwner' })
3988
4205
  ### Core Types
3989
4206
 
3990
4207
  ```typescript
3991
- // Interaction event arguments
4208
+ // EventSource instance interface - the core abstraction for all event sources
4209
+ interface EventSourceInstance<TArgs = any, TResult = void> {
4210
+ uuid: string
4211
+ _type: string
4212
+ name: string
4213
+ entity: EntityInstance
4214
+ guard?: (this: Controller, args: TArgs) => Promise<void>
4215
+ mapEventData?: (args: TArgs) => Record<string, any>
4216
+ resolve?: (this: Controller, args: TArgs) => Promise<TResult>
4217
+ afterDispatch?: (this: Controller, args: TArgs, result: { data?: TResult }) => Promise<Record<string, unknown> | void>
4218
+ }
4219
+
4220
+ // Dispatch response - returned by controller.dispatch()
4221
+ type DispatchResponse = {
4222
+ error?: unknown
4223
+ data?: unknown
4224
+ effects?: RecordMutationEvent[]
4225
+ sideEffects?: { [k: string]: { result?: unknown, error?: unknown } }
4226
+ context?: { [k: string]: unknown }
4227
+ }
4228
+
4229
+ // Interaction event arguments (used when dispatching Interactions)
3992
4230
  type InteractionEventArgs = {
3993
4231
  user: { id: string, [key: string]: any }
3994
4232
  payload?: { [key: string]: any }
3995
- [key: string]: any
4233
+ query?: {
4234
+ match?: any
4235
+ modifier?: Record<string, unknown>
4236
+ attributeQuery?: string[]
4237
+ }
4238
+ context?: Record<string, any>
4239
+ activityId?: string
3996
4240
  }
3997
4241
 
3998
4242
  // Record mutation event
@@ -4048,7 +4292,12 @@ type ComputationResultPatch = {
4048
4292
  ### Complete Blog System Example
4049
4293
 
4050
4294
  ```typescript
4051
- import { Entity, Property, Relation, Interaction, Activity, Controller } from 'interaqt'
4295
+ import {
4296
+ Entity, Property, Relation, Controller,
4297
+ EventSource, Count, Transform, InteractionEventEntity,
4298
+ Action, Payload, PayloadItem, Condition, GetAction, MatchExp
4299
+ } from 'interaqt'
4300
+ import { Interaction } from 'interaqt/builtins'
4052
4301
 
4053
4302
  // 1. Define entities
4054
4303
  const User = Entity.create({
@@ -4059,7 +4308,7 @@ const User = Entity.create({
4059
4308
  Property.create({
4060
4309
  name: 'postCount',
4061
4310
  type: 'number',
4062
- computation: Count.create({ property: 'posts' }) // Use property name from relation
4311
+ computation: Count.create({ property: 'posts' })
4063
4312
  })
4064
4313
  ]
4065
4314
  })
@@ -4072,9 +4321,27 @@ const Post = Entity.create({
4072
4321
  Property.create({
4073
4322
  name: 'likeCount',
4074
4323
  type: 'number',
4075
- computation: Count.create({ property: 'likes' }) // Use property name from relation
4324
+ computation: Count.create({ property: 'likes' })
4076
4325
  })
4077
- ]
4326
+ ],
4327
+ computation: Transform.create({
4328
+ eventDeps: {
4329
+ PostInteraction: {
4330
+ recordName: InteractionEventEntity.name,
4331
+ type: 'create'
4332
+ }
4333
+ },
4334
+ callback: async function(this: Controller, mutationEvent) {
4335
+ const event = mutationEvent.record
4336
+ if (event.interactionName === 'createPost') {
4337
+ return {
4338
+ title: event.payload.postData.title,
4339
+ content: event.payload.postData.content
4340
+ }
4341
+ }
4342
+ return null
4343
+ }
4344
+ })
4078
4345
  })
4079
4346
 
4080
4347
  // 2. Define relations
@@ -4083,7 +4350,25 @@ const UserPostRelation = Relation.create({
4083
4350
  sourceProperty: 'posts',
4084
4351
  target: Post,
4085
4352
  targetProperty: 'author',
4086
- type: '1:n'
4353
+ type: '1:n',
4354
+ computation: Transform.create({
4355
+ eventDeps: {
4356
+ PostInteraction: {
4357
+ recordName: InteractionEventEntity.name,
4358
+ type: 'create'
4359
+ }
4360
+ },
4361
+ callback: async function(this: Controller, mutationEvent) {
4362
+ const event = mutationEvent.record
4363
+ if (event.interactionName === 'createPost') {
4364
+ return {
4365
+ source: event.user,
4366
+ target: event.payload.postData
4367
+ }
4368
+ }
4369
+ return null
4370
+ }
4371
+ })
4087
4372
  })
4088
4373
 
4089
4374
  const PostLikeRelation = Relation.create({
@@ -4094,7 +4379,7 @@ const PostLikeRelation = Relation.create({
4094
4379
  type: 'n:n'
4095
4380
  })
4096
4381
 
4097
- // 3. Define interactions
4382
+ // 3. Define interactions (built-in EventSource type)
4098
4383
  const CreatePostInteraction = Interaction.create({
4099
4384
  name: 'createPost',
4100
4385
  action: Action.create({ name: 'create' }),
@@ -4128,20 +4413,25 @@ const LikePostInteraction = Interaction.create({
4128
4413
  })
4129
4414
  })
4130
4415
 
4131
- // 4. Create controller and initialize system
4416
+ const GetAllPostsInteraction = Interaction.create({
4417
+ name: 'getAllPosts',
4418
+ action: GetAction,
4419
+ data: Post
4420
+ })
4421
+
4422
+ // 4. Create controller with eventSources and initialize
4132
4423
  const controller = new Controller({
4133
- system, // System implementation
4134
- entities: [User, Post], // Entities
4135
- relations: [UserPostRelation, PostLikeRelation], // Relations
4136
- activities: [], // Activities
4137
- interactions: [CreatePostInteraction, LikePostInteraction] // Interactions
4424
+ system,
4425
+ entities: [User, Post],
4426
+ relations: [UserPostRelation, PostLikeRelation],
4427
+ eventSources: [CreatePostInteraction, LikePostInteraction, GetAllPostsInteraction]
4138
4428
  })
4139
4429
 
4140
4430
  await controller.setup(true)
4141
4431
 
4142
- // 5. Use APIs
4432
+ // 5. Use dispatch API
4143
4433
  // Create post
4144
- const result = await controller.callInteraction('createPost', {
4434
+ const result = await controller.dispatch(CreatePostInteraction, {
4145
4435
  user: { id: 'user1' },
4146
4436
  payload: {
4147
4437
  postData: {
@@ -4152,12 +4442,21 @@ const result = await controller.callInteraction('createPost', {
4152
4442
  })
4153
4443
 
4154
4444
  // Like post
4155
- await controller.callInteraction('likePost', {
4445
+ await controller.dispatch(LikePostInteraction, {
4156
4446
  user: { id: 'user2' },
4157
4447
  payload: {
4158
- post: { id: result.recordId }
4448
+ post: { id: 'post1' }
4449
+ }
4450
+ })
4451
+
4452
+ // Get all posts
4453
+ const postsResult = await controller.dispatch(GetAllPostsInteraction, {
4454
+ user: { id: 'user1' },
4455
+ query: {
4456
+ attributeQuery: ['id', 'title', 'content', 'likeCount']
4159
4457
  }
4160
4458
  })
4459
+ // postsResult.data contains the posts
4161
4460
  ```
4162
4461
 
4163
4462
  This API reference documentation covers all core APIs of the interaqt framework, providing complete parameter descriptions and practical usage examples. Developers can quickly get started and deeply use various framework features based on this documentation.