@maxdrellin/xenocline 0.0.1

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 (100) hide show
  1. package/.kodrdriv/config.yaml +10 -0
  2. package/.kodrdriv/context/content.md +26 -0
  3. package/LICENSE.md +66 -0
  4. package/README.md +739 -0
  5. package/__mocks__/src/execution/event.js +8 -0
  6. package/dist/aggregator.d.ts +28 -0
  7. package/dist/aggregator.js +31 -0
  8. package/dist/aggregator.js.map +1 -0
  9. package/dist/constants.d.ts +2 -0
  10. package/dist/context.d.ts +3 -0
  11. package/dist/event/aggregator.d.ts +16 -0
  12. package/dist/event/aggregator.js +29 -0
  13. package/dist/event/aggregator.js.map +1 -0
  14. package/dist/event/event.d.ts +14 -0
  15. package/dist/event/event.js +12 -0
  16. package/dist/event/event.js.map +1 -0
  17. package/dist/event/handler.d.ts +7 -0
  18. package/dist/event/handler.js +8 -0
  19. package/dist/event/handler.js.map +1 -0
  20. package/dist/event/node.d.ts +40 -0
  21. package/dist/event/node.js +24 -0
  22. package/dist/event/node.js.map +1 -0
  23. package/dist/event/phase.d.ts +15 -0
  24. package/dist/event/phase.js +12 -0
  25. package/dist/event/phase.js.map +1 -0
  26. package/dist/event/process.d.ts +14 -0
  27. package/dist/event/process.js +15 -0
  28. package/dist/event/process.js.map +1 -0
  29. package/dist/event/transition.d.ts +45 -0
  30. package/dist/event/transition.js +35 -0
  31. package/dist/event/transition.js.map +1 -0
  32. package/dist/event.d.ts +30 -0
  33. package/dist/execution/aggregator.d.ts +23 -0
  34. package/dist/execution/aggregator.js +81 -0
  35. package/dist/execution/aggregator.js.map +1 -0
  36. package/dist/execution/event.d.ts +26 -0
  37. package/dist/execution/event.js +29 -0
  38. package/dist/execution/event.js.map +1 -0
  39. package/dist/execution/next.d.ts +7 -0
  40. package/dist/execution/next.js +116 -0
  41. package/dist/execution/next.js.map +1 -0
  42. package/dist/execution/node.d.ts +4 -0
  43. package/dist/execution/node.js +170 -0
  44. package/dist/execution/node.js.map +1 -0
  45. package/dist/execution/process.d.ts +35 -0
  46. package/dist/execution/process.js +97 -0
  47. package/dist/execution/process.js.map +1 -0
  48. package/dist/input.d.ts +6 -0
  49. package/dist/input.js +4 -0
  50. package/dist/input.js.map +1 -0
  51. package/dist/logger.d.ts +12 -0
  52. package/dist/node/aggregatornode.d.ts +40 -0
  53. package/dist/node/aggregatornode.js +41 -0
  54. package/dist/node/aggregatornode.js.map +1 -0
  55. package/dist/node/node.d.ts +18 -0
  56. package/dist/node/node.js +80 -0
  57. package/dist/node/node.js.map +1 -0
  58. package/dist/node/phasenode.d.ts +21 -0
  59. package/dist/node/phasenode.js +35 -0
  60. package/dist/node/phasenode.js.map +1 -0
  61. package/dist/output.d.ts +6 -0
  62. package/dist/phase.d.ts +16 -0
  63. package/dist/phase.js +23 -0
  64. package/dist/phase.js.map +1 -0
  65. package/dist/process.d.ts +15 -0
  66. package/dist/process.js +106 -0
  67. package/dist/process.js.map +1 -0
  68. package/dist/transition/beginning.d.ts +19 -0
  69. package/dist/transition/beginning.js +31 -0
  70. package/dist/transition/beginning.js.map +1 -0
  71. package/dist/transition/connection.d.ts +26 -0
  72. package/dist/transition/connection.js +80 -0
  73. package/dist/transition/connection.js.map +1 -0
  74. package/dist/transition/decision.d.ts +20 -0
  75. package/dist/transition/decision.js +47 -0
  76. package/dist/transition/decision.js.map +1 -0
  77. package/dist/transition/next.d.ts +13 -0
  78. package/dist/transition/next.js +81 -0
  79. package/dist/transition/next.js.map +1 -0
  80. package/dist/transition/termination.d.ts +17 -0
  81. package/dist/transition/termination.js +50 -0
  82. package/dist/transition/termination.js.map +1 -0
  83. package/dist/transition/transition.d.ts +16 -0
  84. package/dist/transition/transition.js +72 -0
  85. package/dist/transition/transition.js.map +1 -0
  86. package/dist/util/general.d.ts +4 -0
  87. package/dist/util/general.js +6 -0
  88. package/dist/util/general.js.map +1 -0
  89. package/dist/utility/event/eventfilter.d.ts +7 -0
  90. package/dist/utility/event/eventfilter.js +15 -0
  91. package/dist/utility/event/eventfilter.js.map +1 -0
  92. package/dist/utility/event/filteredhandler.d.ts +13 -0
  93. package/dist/utility/event/filteredhandler.js +18 -0
  94. package/dist/utility/event/filteredhandler.js.map +1 -0
  95. package/dist/utility/event/logginghandler.d.ts +12 -0
  96. package/dist/xenocline.d.ts +72 -0
  97. package/dist/xenocline.js +21 -0
  98. package/dist/xenocline.js.map +1 -0
  99. package/eslint.config.mjs +82 -0
  100. package/package.json +71 -0
@@ -0,0 +1,21 @@
1
+ import { Next } from '../transition/next';
2
+ import { Context } from '../context';
3
+ import { Input } from '../input';
4
+ import { Output } from '../output';
5
+ import { Phase } from '../phase';
6
+ import { Node } from './node';
7
+ export interface PhaseNode<I extends Input = Input, // Input to this phase instance
8
+ O extends Output = Output> extends Node {
9
+ type: 'phase';
10
+ phase: Phase<I, O>;
11
+ }
12
+ export interface PhaseNodeOptions<O extends Output = Output, C extends Context = Context> {
13
+ next?: Next<O, C>;
14
+ }
15
+ export declare const DEFAULT_PHASE_NODE_OPTIONS: PhaseNodeOptions<Output, Context>;
16
+ export declare const createPhaseNode: <I extends Input = Input, O extends Output = Output, C extends Context = Context>(id: string, phase: Phase<I, O>, options?: Partial<PhaseNodeOptions<O, C>>) => Readonly<PhaseNode<I, O>>;
17
+ export declare const isPhaseNode: (obj: any) => obj is PhaseNode<any, any>;
18
+ export declare const validatePhaseNode: (item: any, coordinates?: string[]) => Array<{
19
+ coordinates: string[];
20
+ error: string;
21
+ }>;
@@ -0,0 +1,35 @@
1
+ import { isPhase } from '../phase.js';
2
+ import { createNode, isNode } from './node.js';
3
+ import { clean } from '../util/general.js';
4
+
5
+ const DEFAULT_PHASE_NODE_OPTIONS = {};
6
+ const createPhaseNode = (id, phase, options)=>{
7
+ let phaseNodeOptions = {
8
+ ...DEFAULT_PHASE_NODE_OPTIONS
9
+ };
10
+ if (options) {
11
+ phaseNodeOptions = {
12
+ ...phaseNodeOptions,
13
+ ...clean(options)
14
+ };
15
+ }
16
+ return {
17
+ ...createNode('phase', id, {
18
+ next: phaseNodeOptions.next
19
+ }),
20
+ phase
21
+ };
22
+ };
23
+ const isPhaseNode = (obj)=>{
24
+ if (!isNode(obj) || obj.type !== 'phase') {
25
+ return false;
26
+ }
27
+ const potentialPhaseNode = obj;
28
+ if (!(potentialPhaseNode.phase && typeof potentialPhaseNode.phase === 'object' && isPhase(potentialPhaseNode.phase))) {
29
+ return false;
30
+ }
31
+ return true;
32
+ };
33
+
34
+ export { DEFAULT_PHASE_NODE_OPTIONS, createPhaseNode, isPhaseNode };
35
+ //# sourceMappingURL=phasenode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phasenode.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,6 @@
1
+ export interface Output {
2
+ [key: string]: unknown;
3
+ }
4
+ export declare const EMPTY_OUTPUT: Output;
5
+ export declare const isOutput: (output: unknown) => output is Output;
6
+ export declare const validateOutput: (output: unknown) => output is Output;
@@ -0,0 +1,16 @@
1
+ import { Input } from './input';
2
+ import { Output } from './output';
3
+ export type ExecuteMethod<T extends Input = Input, U extends Output = Output> = (input: T) => Promise<U>;
4
+ export interface Phase<T extends Input = Input, U extends Output = Output> {
5
+ name: string;
6
+ execute: (input: T) => Promise<U>;
7
+ }
8
+ export interface PhaseOptions<T extends Input = Input, U extends Output = Output> {
9
+ execute: ExecuteMethod<T, U>;
10
+ }
11
+ export declare const createPhase: <T extends Input = Input, U extends Output = Output>(name: string, options: Partial<PhaseOptions<T, U>>) => Readonly<Phase<T, U>>;
12
+ export declare const isPhase: <T extends Input = Input, U extends Output = Output>(obj: any) => obj is Phase<T, U>;
13
+ export declare const validatePhase: (item: any, coordinates?: string[]) => Array<{
14
+ coordinates: string[];
15
+ error: string;
16
+ }>;
package/dist/phase.js ADDED
@@ -0,0 +1,23 @@
1
+ import { clean } from './util/general.js';
2
+
3
+ const createPhase = (name, options)=>{
4
+ const defaultOptions = {
5
+ execute: async (input)=>{
6
+ return input;
7
+ }
8
+ };
9
+ const phaseOptions = {
10
+ ...defaultOptions,
11
+ ...clean(options)
12
+ };
13
+ return {
14
+ name,
15
+ execute: phaseOptions.execute
16
+ };
17
+ };
18
+ const isPhase = (obj)=>{
19
+ return obj !== undefined && obj !== null && typeof obj === 'object' && typeof obj.name === 'string' && typeof obj.execute === 'function';
20
+ };
21
+
22
+ export { createPhase, isPhase };
23
+ //# sourceMappingURL=phase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phase.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,15 @@
1
+ import { AggregatorNode } from './node/aggregatornode';
2
+ import { PhaseNode } from './node/phasenode';
3
+ export interface ProcessOptions {
4
+ phases: Record<string, PhaseNode | AggregatorNode>;
5
+ }
6
+ export interface Process {
7
+ name: string;
8
+ phases: Record<string, PhaseNode | AggregatorNode>;
9
+ }
10
+ export declare const createProcess: (name: string, options: Partial<ProcessOptions>) => Readonly<Process>;
11
+ export declare const isProcess: (obj: any) => obj is Process;
12
+ export declare const validateProcess: (item: any, coordinates?: string[]) => Array<{
13
+ coordinates: string[];
14
+ error: string;
15
+ }>;
@@ -0,0 +1,106 @@
1
+ import { validateNode } from './node/node.js';
2
+ import { isConnection } from './transition/connection.js';
3
+ import { clean } from './util/general.js';
4
+
5
+ //import * as ClassifyPhase from './phases/classify';
6
+ // import * as TranscribePhase from './phases/transcribe';
7
+ // import * as ComposePhase from './phases/compose';
8
+ // import * as CompletePhase from './phases/complete';
9
+ const createProcess = (name, options)=>{
10
+ const defaultOptions = {
11
+ phases: {}
12
+ };
13
+ const processOptions = {
14
+ ...defaultOptions,
15
+ ...clean(options)
16
+ };
17
+ // Removed: const eventState = createEventState<C>(processOptions.eventHandlers);
18
+ return {
19
+ name,
20
+ phases: processOptions.phases
21
+ };
22
+ };
23
+ const isProcess = (obj)=>{
24
+ return obj !== undefined && obj !== null && typeof obj === 'object' && typeof obj.name === 'string' && typeof obj.phases === 'object';
25
+ };
26
+ const validateProcess = (item, coordinates)=>{
27
+ const errors = [];
28
+ const currentCoordinates = [
29
+ ...[],
30
+ 'Process'
31
+ ];
32
+ if (item === undefined || item === null) {
33
+ errors.push({
34
+ coordinates: [
35
+ ...currentCoordinates
36
+ ],
37
+ error: 'Process is undefined or null.'
38
+ });
39
+ return errors;
40
+ }
41
+ if (item.name === undefined || typeof item.name !== 'string') {
42
+ errors.push({
43
+ coordinates: [
44
+ ...currentCoordinates
45
+ ],
46
+ error: 'Process name is undefined or not a string.'
47
+ });
48
+ }
49
+ const processNameForPath = typeof item.name === 'string' ? item.name : 'UnnamedProcess';
50
+ const basePath = [
51
+ ...currentCoordinates,
52
+ `name:${processNameForPath}`
53
+ ];
54
+ if (item.phases === undefined || typeof item.phases !== 'object') {
55
+ errors.push({
56
+ coordinates: [
57
+ ...basePath,
58
+ 'phases'
59
+ ],
60
+ error: 'Process phases is undefined or not an object.'
61
+ });
62
+ } else {
63
+ for(const phaseId in item.phases){
64
+ const node = item.phases[phaseId];
65
+ if (Object.prototype.hasOwnProperty.call(item.phases, phaseId)) {
66
+ errors.push(...validateNode(node, [
67
+ ...basePath,
68
+ 'phases',
69
+ phaseId
70
+ ]));
71
+ }
72
+ }
73
+ for(const phaseId in item.phases){
74
+ if (Object.prototype.hasOwnProperty.call(item.phases, phaseId)) {
75
+ const node = item.phases[phaseId];
76
+ if (node && typeof node === 'object' && node.next) {
77
+ if (Array.isArray(node.next)) {
78
+ const transitions = node.next;
79
+ if (transitions.length > 0 && transitions.every((t)=>isConnection(t))) {
80
+ transitions.forEach((connection, index)=>{
81
+ if (connection && typeof connection.targetNodeId === 'string') {
82
+ if (!(connection.targetNodeId in item.phases)) {
83
+ errors.push({
84
+ coordinates: [
85
+ ...basePath,
86
+ 'phases',
87
+ phaseId,
88
+ 'next',
89
+ connection.id || `connection-at-index-${index}`
90
+ ],
91
+ error: `Node "${phaseId}" has a connection to non-existent targetNodeId "${connection.targetNodeId}".`
92
+ });
93
+ }
94
+ } else if (!connection || connection.targetNodeId === undefined) ;
95
+ });
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
102
+ return errors;
103
+ };
104
+
105
+ export { createProcess, isProcess, validateProcess };
106
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,19 @@
1
+ import { Context } from '../context';
2
+ import { Input } from '../input';
3
+ import { Transition } from './transition';
4
+ export type BeginFunction<I extends Input = Input, C extends Context = Context> = (input: I, context: C) => Promise<Input>;
5
+ export interface Beginning<I extends Input = Input, C extends Context = Context> extends Transition {
6
+ type: 'beginning';
7
+ targetNodeId: string;
8
+ begin: BeginFunction<I, C>;
9
+ }
10
+ export interface BeginningOptions<I extends Input = Input, C extends Context = Context> {
11
+ begin: BeginFunction<I, C>;
12
+ }
13
+ export declare const DEFAULT_BEGINNING_OPTIONS: BeginningOptions<Input, Context>;
14
+ export declare const createBeginning: <I extends Input = Input, C extends Context = Context>(id: string, targetNodeId: string, options?: Partial<BeginningOptions<I, C>>) => Readonly<Beginning<I, C>>;
15
+ export declare const isBeginning: <I extends Input = Input, C extends Context = Context>(item: any) => item is Beginning<I, C>;
16
+ export declare const validateBeginning: (item: any, coordinates?: string[]) => Array<{
17
+ coordinates: string[];
18
+ error: string;
19
+ }>;
@@ -0,0 +1,31 @@
1
+ import { clean } from '../util/general.js';
2
+ import { createTransition, isTransition } from './transition.js';
3
+
4
+ // NEW: Termination type extending Transition
5
+ const DEFAULT_BEGINNING_OPTIONS = {
6
+ begin: async (input)=>{
7
+ return input;
8
+ }
9
+ };
10
+ const createBeginning = (id, targetNodeId, options)=>{
11
+ let beginningOptions = {
12
+ ...DEFAULT_BEGINNING_OPTIONS
13
+ };
14
+ if (options) {
15
+ beginningOptions = {
16
+ ...beginningOptions,
17
+ ...clean(options)
18
+ };
19
+ }
20
+ return {
21
+ ...createTransition('beginning', id),
22
+ targetNodeId,
23
+ begin: beginningOptions.begin
24
+ };
25
+ };
26
+ const isBeginning = (item)=>{
27
+ return isTransition(item) && item.type === 'beginning' && (item.begin === undefined || typeof item.begin === 'function');
28
+ };
29
+
30
+ export { DEFAULT_BEGINNING_OPTIONS, createBeginning, isBeginning };
31
+ //# sourceMappingURL=beginning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beginning.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,26 @@
1
+ import { Input } from '../input';
2
+ import { Context } from '../context';
3
+ import { Output } from '../output';
4
+ import { Transition } from './transition';
5
+ export type TransformFunction<O extends Output = Output, C extends Context = Context> = (output: O, context: C) => Promise<[Input, C]>;
6
+ export interface Connection<O extends Output = Output, C extends Context = Context> extends Transition {
7
+ type: 'connection';
8
+ targetNodeId: string;
9
+ transform: TransformFunction<O, C>;
10
+ }
11
+ export interface ConnectionOptions<O extends Output = Output, C extends Context = Context> {
12
+ transform: TransformFunction<O, C>;
13
+ }
14
+ export declare const DEFAULT_CONNECTION_OPTIONS: ConnectionOptions;
15
+ export declare const createConnection: <O extends Output = Output, C extends Context = Context>(id: string, targetNodeId: string, options?: Partial<ConnectionOptions<O, C>>) => Readonly<Connection<O, C>>;
16
+ export declare const isConnection: <O extends Output = Output, C extends Context = Context>(item: any) => item is Connection<O, C>;
17
+ export declare const validateConnection: (item: any, coordinates?: string[]) => Array<{
18
+ coordinates: string[];
19
+ error: string;
20
+ }>;
21
+ /**
22
+ * Event emitted specifically for connection transitions.
23
+ */
24
+ export interface ConnectionEvent extends TransitionEvent {
25
+ transitionType: 'connection';
26
+ }
@@ -0,0 +1,80 @@
1
+ import { createTransition, isTransition, validateTransition } from './transition.js';
2
+ import { clean } from '../util/general.js';
3
+
4
+ const DEFAULT_CONNECTION_OPTIONS = {
5
+ transform: async (output, context)=>{
6
+ return [
7
+ output,
8
+ context
9
+ ];
10
+ }
11
+ };
12
+ const createConnection = (id, targetNodeId, options)=>{
13
+ let connectionOptions = {
14
+ ...DEFAULT_CONNECTION_OPTIONS
15
+ };
16
+ if (options) {
17
+ connectionOptions = {
18
+ ...connectionOptions,
19
+ ...clean(options)
20
+ };
21
+ }
22
+ return {
23
+ ...createTransition('connection', id),
24
+ targetNodeId,
25
+ transform: connectionOptions.transform
26
+ };
27
+ };
28
+ const isConnection = (item)=>{
29
+ return isTransition(item) && item.type === 'connection' && item.targetNodeId !== undefined;
30
+ };
31
+ const validateConnection = (item, coordinates)=>{
32
+ const errors = [];
33
+ const connectionBaseCoordinates = [
34
+ ...coordinates || [],
35
+ 'Connection'
36
+ ];
37
+ errors.push(...validateTransition(item, coordinates));
38
+ if (errors.length === 0) {
39
+ if (item && typeof item === 'object') {
40
+ const connectionSpecificErrorPath = [
41
+ ...connectionBaseCoordinates,
42
+ `Connection: ${item.id}`
43
+ ];
44
+ if (item.type === 'connection') {
45
+ if (typeof item.targetNodeId !== 'string') {
46
+ errors.push({
47
+ coordinates: connectionSpecificErrorPath,
48
+ error: 'Property "targetNodeId" must be a string when type is "connection".'
49
+ });
50
+ }
51
+ // transform is optional, but if present, must be a function.
52
+ if (item.transform !== undefined && typeof item.transform !== 'function') {
53
+ errors.push({
54
+ coordinates: connectionSpecificErrorPath,
55
+ error: 'Optional property "transform" must be a function if present.'
56
+ });
57
+ }
58
+ } else {
59
+ // If type is not 'connection', but these properties exist and are malformed.
60
+ // This primarily helps catch if a non-connection object has these fields incorrectly defined.
61
+ if (item.targetNodeId !== undefined && typeof item.targetNodeId !== 'string') {
62
+ errors.push({
63
+ coordinates: connectionSpecificErrorPath,
64
+ error: 'Property "targetNodeId" is present but is not a string.'
65
+ });
66
+ }
67
+ if (item.transform !== undefined && typeof item.transform !== 'function') {
68
+ errors.push({
69
+ coordinates: connectionSpecificErrorPath,
70
+ error: 'Property "transform" is present but is not a function.'
71
+ });
72
+ }
73
+ }
74
+ }
75
+ }
76
+ return errors;
77
+ };
78
+
79
+ export { DEFAULT_CONNECTION_OPTIONS, createConnection, isConnection, validateConnection };
80
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,20 @@
1
+ import { Termination } from '../xenocline';
2
+ import { Context } from '../context';
3
+ import { Output } from '../output';
4
+ import { Connection } from './connection';
5
+ import { Transition } from './transition';
6
+ export type DecideFunction<O extends Output = Output, C extends Context = Context> = (output: O, context: C) => Promise<Termination<O, C> | Connection<O, C>[]>;
7
+ /**
8
+ * Represents a decision point in the process flow, taking a phase's output and context
9
+ * to determine the next step.
10
+ */
11
+ export interface Decision<O extends Output = Output, C extends Context = Context> extends Transition {
12
+ type: 'decision';
13
+ decide: DecideFunction<O, C>;
14
+ }
15
+ export declare const createDecision: <O extends Output = Output, C extends Context = Context>(id: string, decide: DecideFunction<O, C>) => Readonly<Decision<O, C>>;
16
+ export declare const isDecision: <O extends Output = Output, C extends Context = Context>(item: any) => item is Decision<O, C>;
17
+ export declare const validateDecision: (item: any, coordinates?: string[]) => Array<{
18
+ coordinates: string[];
19
+ error: string;
20
+ }>;
@@ -0,0 +1,47 @@
1
+ import { createTransition, isTransition, validateTransition } from './transition.js';
2
+
3
+ const createDecision = (id, decide)=>{
4
+ return {
5
+ ...createTransition('decision', id),
6
+ decide
7
+ };
8
+ };
9
+ const isDecision = (item)=>{
10
+ return isTransition(item) && item.type === 'decision' && typeof item.decide === 'function';
11
+ };
12
+ const validateDecision = (item, coordinates)=>{
13
+ const errors = [];
14
+ const decisionBaseCoordinates = [
15
+ ...coordinates || [],
16
+ 'Decision'
17
+ ];
18
+ errors.push(...validateTransition(item, coordinates));
19
+ if (errors.length === 0) {
20
+ if (item && typeof item === 'object') {
21
+ const decisionSpecificErrorPath = [
22
+ ...decisionBaseCoordinates,
23
+ `Decision: ${item.id}`
24
+ ];
25
+ if (item.type === 'decision') {
26
+ if (typeof item.decide !== 'function') {
27
+ errors.push({
28
+ coordinates: decisionSpecificErrorPath,
29
+ error: 'Property "decide" must be a function when type is "decision".'
30
+ });
31
+ }
32
+ } else {
33
+ // If type is not 'decision', but 'decide' property exists and is malformed.
34
+ if (item.decide !== undefined && typeof item.decide !== 'function') {
35
+ errors.push({
36
+ coordinates: decisionSpecificErrorPath,
37
+ error: 'Property "decide" is present but is not a function.'
38
+ });
39
+ }
40
+ }
41
+ }
42
+ }
43
+ return errors;
44
+ };
45
+
46
+ export { createDecision, isDecision, validateDecision };
47
+ //# sourceMappingURL=decision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,13 @@
1
+ import { Output } from '../output';
2
+ import { Context } from '../context';
3
+ import { Termination } from './termination';
4
+ import { Connection } from './connection';
5
+ import { Decision } from './decision';
6
+ type NonEmptyArray<T> = [T, ...T[]];
7
+ export type Next<O extends Output = Output, C extends Context = Context> = Termination<O, C> | Readonly<NonEmptyArray<Connection<O, C>>> | Readonly<NonEmptyArray<Decision<O, C>>>;
8
+ export declare const isNext: <O extends Output = Output, C extends Context = Context>(item: any) => item is Next<O, C>;
9
+ export declare const validateNext: (item: any, coordinates?: string[]) => Array<{
10
+ coordinates: string[];
11
+ error: string;
12
+ }>;
13
+ export {};
@@ -0,0 +1,81 @@
1
+ import { validateTermination, isTermination } from './termination.js';
2
+ import { isConnection, validateConnection } from './connection.js';
3
+ import { isDecision, validateDecision } from './decision.js';
4
+
5
+ const isNext = (item)=>{
6
+ if (isTermination(item)) {
7
+ return true;
8
+ }
9
+ if (!Array.isArray(item)) {
10
+ return false;
11
+ }
12
+ if (item.length === 0) {
13
+ return true;
14
+ }
15
+ const firstElement = item[0];
16
+ if (isConnection(firstElement)) {
17
+ return item.every((el)=>isConnection(el));
18
+ }
19
+ if (isDecision(firstElement)) {
20
+ return item.every((el)=>isDecision(el));
21
+ }
22
+ return false;
23
+ };
24
+ const validateDecisionOrConnectionArray = (item, coordinates)=>{
25
+ const errors = [];
26
+ const currentCoordinates = [
27
+ ...coordinates || []
28
+ ];
29
+ if (item.length === 0) {
30
+ errors.push({
31
+ coordinates: [
32
+ ...currentCoordinates
33
+ ],
34
+ error: 'Next Array is empty.'
35
+ });
36
+ return errors;
37
+ }
38
+ const firstElement = item[0];
39
+ if (isConnection(firstElement)) {
40
+ for (const element of item){
41
+ errors.push(...validateConnection(element, currentCoordinates));
42
+ }
43
+ } else if (isDecision(firstElement)) {
44
+ for (const element of item){
45
+ errors.push(...validateDecision(element, currentCoordinates));
46
+ }
47
+ } else {
48
+ errors.push({
49
+ coordinates: [
50
+ ...currentCoordinates
51
+ ],
52
+ error: 'Next Array contains invalid element types. Expected all Connections or all Decisions.'
53
+ });
54
+ }
55
+ return errors;
56
+ };
57
+ const validateNext = (item, coordinates)=>{
58
+ const errors = [];
59
+ const currentCoordinates = [
60
+ ...coordinates || [],
61
+ 'Next'
62
+ ];
63
+ if (item === undefined || item === null) {
64
+ errors.push({
65
+ coordinates: [
66
+ ...currentCoordinates
67
+ ],
68
+ error: 'Next is undefined or null.'
69
+ });
70
+ return errors;
71
+ }
72
+ if (Array.isArray(item)) {
73
+ errors.push(...validateDecisionOrConnectionArray(item, currentCoordinates));
74
+ } else {
75
+ errors.push(...validateTermination(item, currentCoordinates));
76
+ }
77
+ return errors;
78
+ };
79
+
80
+ export { isNext, validateNext };
81
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,17 @@
1
+ import { Context } from '../context';
2
+ import { Output } from '../output';
3
+ import { Transition } from './transition';
4
+ export type TerminateFunction<O extends Output = Output, C extends Context = Context> = (output: O, context: C) => Promise<Output>;
5
+ export interface Termination<O extends Output = Output, C extends Context = Context> extends Transition {
6
+ type: 'termination';
7
+ terminate: TerminateFunction<O, C>;
8
+ }
9
+ export interface TerminationOptions<O extends Output = Output, C extends Context = Context> {
10
+ terminate: TerminateFunction<O, C>;
11
+ }
12
+ export declare const createTermination: <O extends Output = Output, C extends Context = Context>(id: string, options?: Partial<TerminationOptions<O, C>>) => Readonly<Termination<O, C>>;
13
+ export declare const isTermination: <O extends Output = Output, C extends Context = Context>(item: any) => item is Termination<O, C>;
14
+ export declare const validateTermination: (item: any, coordinates?: string[]) => Array<{
15
+ coordinates: string[];
16
+ error: string;
17
+ }>;
@@ -0,0 +1,50 @@
1
+ import { clean } from '../util/general.js';
2
+ import { createTransition, isTransition, validateTransition } from './transition.js';
3
+
4
+ // NEW: Termination type extending Transition
5
+ const createTermination = (id, options)=>{
6
+ const defaultOptions = {
7
+ terminate: async (output)=>{
8
+ return output;
9
+ }
10
+ };
11
+ let terminationOptions = {
12
+ ...defaultOptions
13
+ };
14
+ if (options) {
15
+ terminationOptions = {
16
+ ...terminationOptions,
17
+ ...clean(options)
18
+ };
19
+ }
20
+ return {
21
+ ...createTransition('termination', id),
22
+ terminate: terminationOptions.terminate
23
+ };
24
+ };
25
+ const isTermination = (item)=>{
26
+ return isTransition(item) && item.type === 'termination' && (item.terminate === undefined || typeof item.terminate === 'function');
27
+ };
28
+ const validateTermination = (item, coordinates)=>{
29
+ const errors = [];
30
+ const currentCoordinates = [
31
+ ...coordinates || [],
32
+ 'Termination'
33
+ ];
34
+ errors.push(...validateTransition(item, currentCoordinates));
35
+ if (errors.length === 0) {
36
+ currentCoordinates.push(`Termination: ${item.id}`);
37
+ if (item.terminate !== undefined && typeof item.terminate !== 'function') {
38
+ errors.push({
39
+ coordinates: [
40
+ ...currentCoordinates
41
+ ],
42
+ error: 'terminate is not a function.'
43
+ });
44
+ }
45
+ }
46
+ return errors;
47
+ };
48
+
49
+ export { createTermination, isTermination, validateTermination };
50
+ //# sourceMappingURL=termination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"termination.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}