diff --git a/README.md b/README.md index 8222b23..c39e6fa 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,14 @@ sequenceDiagram participant Aquila as Aquila (Server) participant Stream as Stream (gRPC) + Hercules->>Aquila: Register datatypes
because maybe they are needed in the config definitions + Aquila-->>Hercules: Validation result + + Hercules->>Stream: Open bi-directional stream Hercules->>Stream: ActionLogon request - Hercules->>Aquila: Register datatypes - Aquila-->>Hercules: Validation result - + Hercules->>Aquila: Register function definitions Aquila-->>Hercules: Validation result @@ -59,4 +61,4 @@ To use a simple test server use the following command: ```bash ./bin/test_server.rb ``` -This will start a test server on `localhost:50051` that you can connect to with the action sdk. \ No newline at end of file +This will start a test server on `localhost:50051` that you can connect to with the action sdk. diff --git a/bin/Gemfile b/bin/Gemfile index 22c8cd7..23c96af 100644 --- a/bin/Gemfile +++ b/bin/Gemfile @@ -1,7 +1,8 @@ +# frozen_string_literal: true + source 'https://rubygems.org' ruby '3.4.7' - -gem 'tucana', '0.0.56' gem 'grpc', '~> 1.67' +gem 'tucana', '0.0.57' diff --git a/bin/Gemfile.lock b/bin/Gemfile.lock index 77057d1..a0fe082 100644 --- a/bin/Gemfile.lock +++ b/bin/Gemfile.lock @@ -17,7 +17,7 @@ GEM google-protobuf (>= 3.25, < 5.0) googleapis-common-protos-types (~> 1.0) rake (13.3.1) - tucana (0.0.56) + tucana (0.0.57) grpc (~> 1.64) PLATFORMS @@ -26,7 +26,7 @@ PLATFORMS DEPENDENCIES grpc (~> 1.67) - tucana (= 0.0.56) + tucana (= 0.0.57) RUBY VERSION ruby 3.4.7p58 diff --git a/bin/test_server.rb b/bin/test_server.rb index f870f9e..cd4d80e 100755 --- a/bin/test_server.rb +++ b/bin/test_server.rb @@ -93,7 +93,8 @@ def construct_parameters(func) end def transfer(requests, call) - puts "Got Auth token: #{call.metadata['authorization']}" + token = call.metadata['authorization'] + puts "Got Auth token: #{token}" Enumerator.new do |yielder| Thread.new do loop do @@ -133,6 +134,7 @@ def transfer(requests, call) yielder << Tucana::Aquila::TransferResponse.new( { execution: Tucana::Aquila::ExecutionRequest.new( + project_id: Random.rand(1..1000), execution_identifier: exec_identifier, function_identifier: func.runtime_name, parameters: construct_parameters(func) @@ -156,12 +158,12 @@ def transfer(requests, call) puts "Project id: #{req.event.project_id}" next end - next if req.logon.nil? logon = req.logon @state.add_action_config_definition({ + auth_token: token, action_identifier: logon.action_identifier, version: logon.version, config_definitions: logon.action_configurations, diff --git a/ts/bun.lock b/ts/bun.lock index b7857f9..a46996d 100644 --- a/ts/bun.lock +++ b/ts/bun.lock @@ -5,7 +5,7 @@ "": { "name": "ts", "dependencies": { - "@code0-tech/tucana": "^0.0.56", + "@code0-tech/tucana": "^0.0.58", "@grpc/grpc-js": "^1.14.3", "@protobuf-ts/grpc-transport": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", @@ -21,7 +21,7 @@ }, }, "packages": { - "@code0-tech/tucana": ["@code0-tech/tucana@0.0.56", "", {}, "sha512-tU/5HaqdKBIMIvJFbMJfPMDhqGIS48oyRis2M2ykrrzkEa9DjLjXDKmh4NmCaDQddP3IXPZp/4PJUC+SDWCV/g=="], + "@code0-tech/tucana": ["@code0-tech/tucana@0.0.58", "", {}, "sha512-0kLzp/2y4aGiAW3SEwPnJXLhRIafuMEPa3f+sR7y/hb4JsSAn3/hMHAbtUee7axW8u4BCek7SX+Hyn68GP1CNQ=="], "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], diff --git a/ts/examples/simple_example.ts b/ts/examples/simple_example.ts index b8f62f6..7da9da5 100644 --- a/ts/examples/simple_example.ts +++ b/ts/examples/simple_example.ts @@ -1,101 +1,59 @@ -import { createSdk } from "../src/action_sdk.js"; -import { Struct, Value } from "@code0-tech/tucana/pb/shared.struct_pb.js"; -import { constructValue } from "@code0-tech/tucana/helpers/shared.struct_helper.js"; -import { ActionProjectConfiguration } from "@code0-tech/tucana/pb/shared.action_configuration_pb.js"; +import {createSdk} from "../src/action_sdk.js"; +import {constructValue} from "@code0-tech/tucana/helpers/shared.struct_helper.js"; +import {ActionProjectConfiguration} from "@code0-tech/tucana/pb/shared.action_configuration_pb.js"; +import {HerculesFunctionContext} from "../src/types.js"; const sdk = createSdk({ - token: "your_token_here", - actionUrl: "127.0.0.1:50051", + authToken: "someToken", + aquilaUrl: "127.0.0.1:50051", actionId: "action_123", version: "0.0.0", -}) - -sdk.registerConfigDefinitions({ - type: { - signature: "string", - identifier: "STRING", - version: "0.0.0", - rules: [], - name: [], - genericKeys: [], - alias: [], - displayMessage: [], - linkedDataTypeIdentifiers: [], - definitionSource: "" - }, - name: [], - description: [], - identifier: "config_discord_bot_token", -}) +}, [ + { + type: "LIST", + linkedDataTypeIdentifiers: ["STRING", "LIST"], + identifier: "config_discord_bot_token", + } +]) sdk.registerDataType({ identifier: "SOME_DATATYPE", - signature: "any", - name: [], - alias: [], - rules: [], - genericKeys: [], - displayMessage: [], - definitionSource: "", - linkedDataTypeIdentifiers: [], - version: "0.0.0", + type: "any", }) sdk.registerFunctionDefinition( { signature: "(n: NUMBER) => NUMBER", - definitionSource: "", linkedDataTypeIdentifiers: ["NUMBER"], - runtimeParameterDefinitions: [ + parameters: [ { runtimeName: "n", - description: [], - name: [], - documentation: [], - defaultValue: constructValue(20), + defaultValue: 20, } ], - alias: [], - deprecationMessage: [], - description: [], - displayIcon: "", - displayMessage: [], - documentation: [], - name: [], - throwsError: false, - version: "0.0.0", runtimeName: "fib", }, - async (params: Struct): Promise => { - console.log("Received parameters:", params); - let n = params.fields["n"]; + // This param is optional and can be omitted + (n: number, context: HerculesFunctionContext): number => { + console.log(context) + console.log("Project id:", context.projectId); + console.log("Execution id:", context.executionId); + console.log("Matched configs:", context.matchedConfigs); // matched configs for the current execution function fibonacci(num: number): number { if (num <= 1) return num; return fibonacci(num - 1) + fibonacci(num - 2); } - if (n && n.kind.oneofKind === "numberValue") { - return constructValue(fibonacci(n.kind.numberValue)); - } - - return constructValue(fibonacci(1)); + return fibonacci(n) } ) sdk.registerFlowType( { - documentation: [], - description: [], - displayIcon: "", - displayMessage: [], editable: false, - inputTypeIdentifier: "STRING", - name: [], - alias: [], + inputType: "STRING", identifier: "test_flow", - settings: [], - version: "0.0.0", } ) @@ -119,4 +77,4 @@ function connectToSdk() { connectToSdk(); }, 5000) }) -} \ No newline at end of file +} diff --git a/ts/package-lock.json b/ts/package-lock.json index b9c60fd..49ac935 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@code0-tech/tucana": "^0.0.52", + "@code0-tech/tucana": "^0.0.58", "@grpc/grpc-js": "^1.14.3", "@protobuf-ts/grpc-transport": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", @@ -24,9 +24,9 @@ } }, "node_modules/@code0-tech/tucana": { - "version": "0.0.52", - "resolved": "https://registry.npmjs.org/@code0-tech/tucana/-/tucana-0.0.52.tgz", - "integrity": "sha512-Pk78QdH6Ino4crHzhjhzYoRQSfCTGdc8W7u9SQc/vBJxO2TiVL2rVJ/KKgzlSQU/2r8Ijn/Zl3GYRlSgiPRnJQ==", + "version": "0.0.58", + "resolved": "https://registry.npmjs.org/@code0-tech/tucana/-/tucana-0.0.58.tgz", + "integrity": "sha512-0kLzp/2y4aGiAW3SEwPnJXLhRIafuMEPa3f+sR7y/hb4JsSAn3/hMHAbtUee7axW8u4BCek7SX+Hyn68GP1CNQ==", "license": "Apache-2.0" }, "node_modules/@cspotcode/source-map-support": { diff --git a/ts/package.json b/ts/package.json index a195a3c..2a9381f 100644 --- a/ts/package.json +++ b/ts/package.json @@ -21,7 +21,7 @@ "license": "ISC", "type": "module", "dependencies": { - "@code0-tech/tucana": "^0.0.56", + "@code0-tech/tucana": "^0.0.58", "@grpc/grpc-js": "^1.14.3", "@protobuf-ts/grpc-transport": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", diff --git a/ts/src/action_sdk.ts b/ts/src/action_sdk.ts index f86db14..47f52ed 100644 --- a/ts/src/action_sdk.ts +++ b/ts/src/action_sdk.ts @@ -1,15 +1,15 @@ -import {FlowType} from "@code0-tech/tucana/pb/shared.flow_definition_pb.js"; -import {DefinitionDataType} from "@code0-tech/tucana/pb/shared.data_type_pb.js"; -import {RuntimeFunctionDefinition} from "@code0-tech/tucana/pb/shared.runtime_function_pb.js"; -import {Struct, Value} from "@code0-tech/tucana/pb/shared.struct_pb.js"; -import {GrpcOptions, GrpcTransport} from "@protobuf-ts/grpc-transport"; +import {GrpcTransport} from "@protobuf-ts/grpc-transport"; import {ChannelCredentials} from "@grpc/grpc-js"; import {ActionTransferServiceClient} from "@code0-tech/tucana/pb/aquila.action_pb.client.js"; -import {DuplexStreamingCall, RpcOptions} from "@protobuf-ts/runtime-rpc"; -import {ExecutionRequest, TransferRequest, TransferResponse} from "@code0-tech/tucana/pb/aquila.action_pb.js"; -import {constructValue} from "@code0-tech/tucana/helpers/shared.struct_helper.js"; +import {RpcOptions} from "@protobuf-ts/runtime-rpc"; import { - ActionConfigurationDefinition, ActionConfigurations, + ExecutionRequest, + TransferRequest, + TransferResponse +} from "@code0-tech/tucana/pb/aquila.action_pb.js"; +import {constructValue, toAllowedValue} from "@code0-tech/tucana/helpers/shared.struct_helper.js"; +import { + ActionConfigurations, ActionProjectConfiguration } from "@code0-tech/tucana/pb/shared.action_configuration_pb"; import {DataTypeServiceClient} from "@code0-tech/tucana/pb/aquila.data_type_pb.client"; @@ -18,47 +18,14 @@ import {RuntimeFunctionDefinitionServiceClient} from "@code0-tech/tucana/pb/aqui import {RuntimeFunctionDefinitionUpdateRequest} from "@code0-tech/tucana/pb/aquila.runtime_function_pb"; import {FlowTypeServiceClient} from "@code0-tech/tucana/pb/aquila.flow_type_pb.client"; import {FlowTypeUpdateRequest} from "@code0-tech/tucana/pb/aquila.flow_type_pb"; +import {ActionSdk, HerculesActionConfigurationDefinition, HerculesFunctionContext, SdkState} from "./types"; +import {FlowTypeSetting, FlowTypeSetting_UniquenessScope} from "@code0-tech/tucana/pb/shared.flow_definition_pb"; -type ActionSdk = { - config: { - token: string, - actionUrl: string, - actionId: string, - version: string, - }, - fullyConnected: () => boolean, // indicates whether the SDK is fully connected and ready to send/receive messages. Becomes true after connect() resolves successfully - connect: (options?: GrpcOptions) => Promise, // after registering the functions and events - onError: (handler: (error: Error) => void) => void, - getProjectActionConfigurations(): ActionProjectConfiguration[], - registerConfigDefinitions: (...actionConfigurations: ActionConfigurationDefinition[]) => Promise, - registerDataType: (dataType: Omit) => Promise, - registerFlowType: (flowType: Omit) => Promise, - registerFunctionDefinition: (functionDefinition: Omit, handler: (parameters: Struct) => Promise) => Promise, - dispatchEvent: (eventType: string, projectId: number | bigint, payload: Value) => Promise, -} - -type RegisteredFunction = { - identifier: string, - definition: Omit, - handler: (parameters: Struct) => Promise, -} -type SdkState = { - functions: RegisteredFunction[], - dataTypes: DefinitionDataType[], - flowTypes: FlowType[], - configurationDefinitions: ActionConfigurationDefinition[], - projectConfigurations: ActionProjectConfiguration[], - transport: GrpcTransport, - client: ActionTransferServiceClient, - stream: DuplexStreamingCall | undefined, - fullyConnected: boolean, -} - -export const createSdk = (config: ActionSdk["config"]): ActionSdk => { +export const createSdk = (config: ActionSdk["config"], configDefinitions?: HerculesActionConfigurationDefinition[]): ActionSdk => { const transport = new GrpcTransport( { - host: config.actionUrl, + host: config.aquilaUrl, channelCredentials: ChannelCredentials.createInsecure() } ) @@ -68,7 +35,16 @@ export const createSdk = (config: ActionSdk["config"]): ActionSdk => { functions: [], dataTypes: [], flowTypes: [], - configurationDefinitions: [], + configurationDefinitions: configDefinitions?.map(value => { + return { + identifier: value.identifier, + name: value.name || [], + description: value.description || [], + type: value.type, + linkedDataTypeIdentifiers: value.linkedDataTypeIdentifiers || [], + defaultValue: constructValue(value.defaultValue || null), + } + }) || [], projectConfigurations: [], transport: transport, client: client, @@ -90,22 +66,89 @@ export const createSdk = (config: ActionSdk["config"]): ActionSdk => { getProjectActionConfigurations: () => { return state.projectConfigurations; }, - registerConfigDefinitions: async (actionConfigurations) => { - state.configurationDefinitions = state.configurationDefinitions.concat(actionConfigurations); + registerConfigDefinitions: async (...actionConfigurations) => { + state.configurationDefinitions.push(...(actionConfigurations?.map(value => { + return { + identifier: value.identifier, + name: value.name || [], + description: value.description || [], + type: value.type, + linkedDataTypeIdentifiers: value.linkedDataTypeIdentifiers || [], + defaultValue: constructValue(value.defaultValue || null), + } + }) || [])) + return Promise.resolve() }, registerDataType: async (dataType) => { - state.dataTypes.push(dataType); + state.dataTypes.push({ + identifier: dataType.identifier, + name: dataType.name || [], + alias: dataType.alias || [], + rules: dataType.rules || [], + genericKeys: dataType.genericKeys || [], + type: dataType.type, + linkedDataTypeIdentifiers: dataType.linkedDataTypeIdentifiers || [], + displayMessage: dataType.displayMessage || [], + definitionSource: "action", + version: dataType.version || config.version, + }); + + return Promise.resolve() }, registerFlowType: async (flowType) => { - state.flowTypes.push(flowType); + state.flowTypes.push({ + identifier: flowType.identifier, + name: flowType.name || [], + alias: flowType.alias || [], + description: flowType.description || [], + displayIcon: flowType.displayIcon || "", + displayMessage: flowType.displayMessage || [], + documentation: flowType.documentation || [], + definitionSource: "action", + version: flowType.version || config.version, + inputType: flowType.inputType || "", + returnType: flowType.returnType || "", + linkedDataTypeIdentifiers: flowType.linkedDataTypeIdentifiers || [], + settings: (flowType.settings || []).map(setting => ({ + name: setting.name || [], + defaultValue: constructValue(setting.defaultValue || null), + identifier: setting.identifier, + description: setting.description || [], + unique: setting.unique || FlowTypeSetting_UniquenessScope.NONE, + type: setting.dataTypeIdentifier, + linkedDataTypeIdentifiers: setting.linkedDataTypeIdentifiers || [], + } as FlowTypeSetting)), + editable: flowType.editable || false + }); return Promise.resolve() }, registerFunctionDefinition: async (functionDefinition, handler) => { state.functions.push({ identifier: functionDefinition.runtimeName, - definition: functionDefinition, + definition: { + displayMessage: functionDefinition.displayMessage || [], + name: functionDefinition.name || [], + documentation: functionDefinition.documentation || [], + description: functionDefinition.description || [], + deprecationMessage: functionDefinition.deprecationMessage || [], + displayIcon: functionDefinition.displayIcon || "", + alias: functionDefinition.alias || [], + linkedDataTypeIdentifiers: functionDefinition.linkedDataTypeIdentifiers || [], + definitionSource: "action", + version: functionDefinition.version || config.version, + runtimeName: functionDefinition.runtimeName, + runtimeParameterDefinitions: (functionDefinition.parameters || []).map(param => ({ + runtimeName: param.runtimeName, + name: param.name || [], + description: param.description || [], + documentation: param.documentation || [], + defaultValue: constructValue(param.defaultValue || null), + })), + signature: functionDefinition.signature, + throwsError: functionDefinition.throwsError || false, + }, handler: handler, }); return Promise.resolve() @@ -125,7 +168,7 @@ export const createSdk = (config: ActionSdk["config"]): ActionSdk => { event: { projectId: projectIdBigInt, eventType: eventType, - payload: payload || constructValue(null), + payload: constructValue(payload) || constructValue(null), } } }) @@ -138,15 +181,29 @@ export const createSdk = (config: ActionSdk["config"]): ActionSdk => { } } -async function connect(state: SdkState, config: ActionSdk["config"], options?: RpcOptions): Promise { +async function connect(state: SdkState, config: ActionSdk["config"], options?: RpcOptions): Promise { const builtOptions: RpcOptions = { meta: { - "Authorization": config.token, + "Authorization": config.authToken, }, ...options } state.stream = state.client.transfer(builtOptions); + const dataTypeClient = new DataTypeServiceClient(state.transport) + await dataTypeClient.update(DataTypeUpdateRequest.create({ + dataTypes: [ + ...state.dataTypes + ] + }), builtOptions).then(value => { + if (!value.response.success) { + return Promise.reject(value.response); + } + }).catch(reason => { + return Promise.reject(reason); + }) + + await state.stream.requests.send( TransferRequest.create({ data: { @@ -163,18 +220,6 @@ async function connect(state: SdkState, config: ActionSdk["config"], options?: return Promise.reject(reason); }) - const dataTypeClient = new DataTypeServiceClient(state.transport) - await dataTypeClient.update(DataTypeUpdateRequest.create({ - dataTypes: [ - ...state.dataTypes - ] - }), builtOptions).then(value => { - if (!value.response.success) { - return Promise.reject(value.response); - } - }).catch(reason => { - return Promise.reject(reason); - }) const runtimeFunctionDefinitionClient = new RuntimeFunctionDefinitionServiceClient(state.transport) await runtimeFunctionDefinitionClient.update( RuntimeFunctionDefinitionUpdateRequest.create( @@ -239,24 +284,42 @@ function handleExecutionRequest(state: SdkState, message: TransferResponse): Pro const execution = message.data.execution as ExecutionRequest; const func = state.functions.find(value => value.identifier == execution.functionIdentifier); if (func) { - func.handler(execution.parameters!).then(async value => { - try { - console.log("Execution result:", value); - return await state.stream!.requests.send( - TransferRequest.create({ - data: { - oneofKind: "result", - result: { - executionIdentifier: execution.executionIdentifier, - result: value || constructValue(null), - } - } - }) - ); - } catch (reason) { - return reject(reason); - } + const params = Object.values(execution!.parameters!.fields!).map(value => { + return toAllowedValue(value) }) + + const context: HerculesFunctionContext = { + projectId: execution.projectId, + executionId: execution.executionIdentifier, + matchedConfigs: state.projectConfigurations.filter(config => { + return config.projectId === execution.projectId + }) || [], + } + + if (func.handler.length == params.length + 1) { + // handler has context parameter + params.push(context) + } else if (func.handler.length > params.length + 1) { + reject(new Error("Handler has more parameters than provided arguments")) + return + } + + const result = func.handler(...params) + try { + return await state.stream!.requests.send( + TransferRequest.create({ + data: { + oneofKind: "result", + result: { + executionIdentifier: execution.executionIdentifier, + result: constructValue(result), + } + } + }) + ); + } catch (reason) { + return reject(reason); + } } resolve(); }) diff --git a/ts/src/types.ts b/ts/src/types.ts new file mode 100644 index 0000000..32a4fd4 --- /dev/null +++ b/ts/src/types.ts @@ -0,0 +1,130 @@ +import {FlowType, FlowTypeSetting_UniquenessScope} from "@code0-tech/tucana/pb/shared.flow_definition_pb.js"; +import { DefinitionDataType, DefinitionDataTypeRule } from "@code0-tech/tucana/pb/shared.data_type_pb.js"; +import { RuntimeFunctionDefinition } from "@code0-tech/tucana/pb/shared.runtime_function_pb.js"; +import { Value } from "@code0-tech/tucana/pb/shared.struct_pb.js"; +import { GrpcOptions, GrpcTransport } from "@protobuf-ts/grpc-transport"; +import { ActionTransferServiceClient } from "@code0-tech/tucana/pb/aquila.action_pb.client.js"; +import { DuplexStreamingCall } from "@protobuf-ts/runtime-rpc"; +import { + TransferRequest, + TransferResponse +} from "@code0-tech/tucana/pb/aquila.action_pb.js"; +import { + ActionConfigurationDefinition, ActionProjectConfiguration +} from "@code0-tech/tucana/pb/shared.action_configuration_pb"; +import {Translation} from "@code0-tech/tucana/pb/shared.translation_pb"; +import {PlainValue} from "@code0-tech/tucana/helpers/shared.struct_helper"; + +export interface HerculesFunctionContext { + projectId: number | bigint, + executionId: string, + matchedConfigs: ActionProjectConfiguration[] +} + +export interface HerculesDefinitionDataType { + identifier: string, + name?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + rules?: DefinitionDataTypeRule[], + genericKeys?: string[], + type: string, + linkedDataTypeIdentifiers?: string[], + // Will default to sdk version + version?: string +} + +export interface HerculesFlowTypeSetting { + identifier: string, + unique?: FlowTypeSetting_UniquenessScope, + dataTypeIdentifier: string, + linkedDataTypeIdentifiers?: string[], + defaultValue?: PlainValue, + name?: Translation[], + description?: Translation[], +} + +export interface HerculesFlowType { + identifier: string, + settings?: HerculesFlowTypeSetting[] + inputType?: string, + returnType?: string, + linkedDataTypeIdentifiers?: string[], + editable: boolean, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + version?: string, + displayIcon?: string, +} + +export interface HerculesRuntimeFunctionDefinition { + runtimeName: string, + parameters?: { + runtimeName: string, + defaultValue?: PlainValue, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + }[], + signature: string, + throwsError?: boolean, + name?: Translation[], + description?: Translation[], + documentation?: Translation[], + deprecationMessage?: Translation[], + displayMessage?: Translation[], + alias?: Translation[], + linkedDataTypeIdentifiers?: string[], + version?: string, + displayIcon?: string, +} + +export interface HerculesActionConfigurationDefinition { + name?: Translation[], + description?: Translation[], + type: string, + linkedDataTypeIdentifiers?: string[], + defaultValue?: PlainValue, + identifier: string, +} + +export interface ActionSdk { + config: { + authToken: string, + aquilaUrl: string, + actionId: string, + version: string, + }, + fullyConnected: () => boolean, // indicates whether the SDK is fully connected and ready to send/receive messages. Becomes true after connect() resolves successfully + connect: (options?: GrpcOptions) => Promise, // after registering the functions and events + onError: (handler: (error: Error) => void) => void, + + getProjectActionConfigurations(): ActionProjectConfiguration[], + + registerConfigDefinitions: (...actionConfigurations: Array) => Promise, + registerDataType: (dataType: HerculesDefinitionDataType) => Promise, + registerFlowType: (flowType: HerculesFlowType) => Promise, + registerFunctionDefinition: (functionDefinition: HerculesRuntimeFunctionDefinition, handler: Function) => Promise, + dispatchEvent: (eventType: string, projectId: number | bigint, payload: PlainValue) => Promise, +} + +export interface RegisteredFunction { + identifier: string, + definition: RuntimeFunctionDefinition, + handler: Function +} + +export interface SdkState { + functions: RegisteredFunction[], + dataTypes: DefinitionDataType[], + flowTypes: FlowType[], + configurationDefinitions: ActionConfigurationDefinition[], + projectConfigurations: ActionProjectConfiguration[], + transport: GrpcTransport, + client: ActionTransferServiceClient, + stream: DuplexStreamingCall | undefined, + fullyConnected: boolean, +}