@integration-app/sdk
Advanced tools
Comparing version 0.1.4 to 0.1.5
@@ -21,2 +21,5 @@ export interface IntegrationAppClientOptions { | ||
openNewFlow(options: NewFlowOptions): Promise<void>; | ||
runFlow(flowId: string, options?: RunFlowOptions): Promise<unknown>; | ||
getFlowNodeRunOutput(flowNodeRunId: string): Promise<any>; | ||
getFlowRunOutput(flowRun: any): Promise<any>; | ||
private getEmbedUri; | ||
@@ -41,2 +44,7 @@ get(uri: string): Promise<any>; | ||
} | ||
export interface RunFlowOptions { | ||
onSuccess?: (...args: any) => void; | ||
onFailure?: (...args: any) => void; | ||
onUpdate?: (...args: any) => void; | ||
} | ||
export interface NewConnectionOptions { | ||
@@ -43,0 +51,0 @@ integratedAppKey: string; |
@@ -20,2 +20,16 @@ "use strict"; | ||
const DEFAULT_UI_URI = 'https://ui.integration.app'; | ||
/* TODO: should we use `common` folder here? */ | ||
var FlowRunState; | ||
(function (FlowRunState) { | ||
FlowRunState["RUNNING"] = "running"; | ||
FlowRunState["COMPLETED"] = "completed"; | ||
FlowRunState["FAILED"] = "failed"; | ||
})(FlowRunState || (FlowRunState = {})); | ||
var FlowNodeRunState; | ||
(function (FlowNodeRunState) { | ||
FlowNodeRunState["RUNNING"] = "running"; | ||
FlowNodeRunState["COMPLETED_ITERATION"] = "completed_iteration"; | ||
FlowNodeRunState["COMPLETED"] = "completed"; | ||
FlowNodeRunState["FAILED"] = "failed"; | ||
})(FlowNodeRunState || (FlowNodeRunState = {})); | ||
class IntegrationEngineClient { | ||
@@ -125,2 +139,96 @@ constructor(options) { | ||
} | ||
runFlow(flowId, options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { id: flowRunId } = yield this.post('flow-runs', { flowId: flowId }); | ||
let flowRun; | ||
let checkFlowRunInterval; | ||
let checkFlowNodeRunsInterval; | ||
const thisGet = this.get.bind(this); | ||
function updateFlowRun(nextFlowRun) { | ||
flowRun = Object.assign(Object.assign({}, flowRun), nextFlowRun); | ||
} | ||
function updateFlowNodeRuns(nextFlowNodeRuns) { | ||
flowRun = Object.assign(Object.assign({}, flowRun), { nodeRuns: nextFlowNodeRuns }); | ||
} | ||
function cleanup() { | ||
checkFlowRunInterval && clearInterval(checkFlowRunInterval); | ||
checkFlowNodeRunsInterval && clearInterval(checkFlowNodeRunsInterval); | ||
} | ||
function completeFlowRunNodes() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!(flowRun === null || flowRun === void 0 ? void 0 : flowRun.nodeRuns)) { | ||
return; | ||
} | ||
const flowNodeRunFetches = flowRun.nodeRuns.map((nodeRun) => { | ||
if ((nodeRun === null || nodeRun === void 0 ? void 0 : nodeRun.state) === FlowNodeRunState.COMPLETED) { | ||
return nodeRun; | ||
} | ||
return thisGet(`flow-node-runs/${nodeRun.id}`); | ||
}); | ||
const flowNodeRuns = yield Promise.all([...flowNodeRunFetches]); | ||
updateFlowNodeRuns(flowNodeRuns); | ||
}); | ||
} | ||
return new Promise((resolve, reject) => { | ||
function onUpdate() { | ||
options.onUpdate && options.onUpdate(flowRun); | ||
} | ||
function onSuccess() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield completeFlowRunNodes(); | ||
options.onSuccess && options.onSuccess(flowRun); | ||
resolve(flowRun); | ||
cleanup(); | ||
}); | ||
} | ||
function onFailure() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield completeFlowRunNodes(); | ||
options.onFailure && options.onFailure(flowRun); | ||
reject(flowRun); | ||
cleanup(); | ||
}); | ||
} | ||
/* POLLING */ | ||
checkFlowNodeRunsInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () { | ||
const flowNodeRunsNext = yield this.get(`flow-node-runs?filter[flowRunId]=${flowRunId}`); | ||
updateFlowNodeRuns(flowNodeRunsNext); | ||
}), 1000); | ||
checkFlowRunInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () { | ||
const flowRunLatest = yield thisGet(`flow-runs/${flowRunId}`); | ||
updateFlowRun(flowRunLatest); | ||
switch (flowRunLatest.state) { | ||
case FlowRunState.COMPLETED: | ||
yield onSuccess(); | ||
break; | ||
case FlowRunState.FAILED: | ||
yield onFailure(); | ||
break; | ||
default: | ||
onUpdate(); | ||
} | ||
}), 1000); | ||
/* PUSHER */ | ||
}); | ||
}); | ||
} | ||
getFlowNodeRunOutput(flowNodeRunId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.get(`flow-node-runs/${flowNodeRunId}/output`); | ||
}); | ||
} | ||
getFlowRunOutput(flowRun) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const latestNodeRun = flowRun.nodeRuns | ||
// ids are created by MongoDB and are sequential | ||
.sort((r1, r2) => (r1.id > r2.id ? 1 : -1)) | ||
.pop(); | ||
if (latestNodeRun) { | ||
return this.getFlowNodeRunOutput(latestNodeRun.id); | ||
} | ||
else { | ||
return undefined; | ||
} | ||
}); | ||
} | ||
getEmbedUri(page, params) { | ||
@@ -127,0 +235,0 @@ const embedUrl = new URL(`${this.uiUri}/embed/${page}`); |
{ | ||
"name": "@integration-app/sdk", | ||
"version": "0.1.4", | ||
"version": "0.1.5", | ||
"description": "JavaScript SDK for Integration.app", | ||
@@ -25,4 +25,5 @@ "main": "dist/index.js", | ||
"insert-css": "^2.0.0", | ||
"penpal": "^5.3.0" | ||
"penpal": "^5.3.0", | ||
"pusher-js": "^7.0.3" | ||
} | ||
} |
@@ -7,2 +7,16 @@ import Axios, { AxiosRequestConfig } from 'axios' | ||
/* TODO: should we use `common` folder here? */ | ||
enum FlowRunState { | ||
RUNNING = 'running', | ||
COMPLETED = 'completed', | ||
FAILED = 'failed', | ||
} | ||
enum FlowNodeRunState { | ||
RUNNING = 'running', | ||
COMPLETED_ITERATION = 'completed_iteration', | ||
COMPLETED = 'completed', | ||
FAILED = 'failed', | ||
} | ||
export interface IntegrationAppClientOptions { | ||
@@ -122,2 +136,105 @@ accessToken?: string | ||
public async runFlow(flowId: string, options: RunFlowOptions = {}) { | ||
const { id: flowRunId } = await this.post('flow-runs', { flowId: flowId }) | ||
let flowRun: Record<string, any> | ||
let checkFlowRunInterval: ReturnType<typeof setInterval> | ||
let checkFlowNodeRunsInterval: ReturnType<typeof setInterval> | ||
const thisGet = this.get.bind(this) | ||
function updateFlowRun(nextFlowRun: Record<string, any>) { | ||
flowRun = { ...flowRun, ...nextFlowRun } | ||
} | ||
function updateFlowNodeRuns(nextFlowNodeRuns: any[]) { | ||
flowRun = { ...flowRun, nodeRuns: nextFlowNodeRuns } | ||
} | ||
function cleanup() { | ||
checkFlowRunInterval && clearInterval(checkFlowRunInterval) | ||
checkFlowNodeRunsInterval && clearInterval(checkFlowNodeRunsInterval) | ||
} | ||
async function completeFlowRunNodes() { | ||
if (!flowRun?.nodeRuns) { | ||
return | ||
} | ||
const flowNodeRunFetches = flowRun.nodeRuns.map( | ||
(nodeRun: Record<string, any>) => { | ||
if (nodeRun?.state === FlowNodeRunState.COMPLETED) { | ||
return nodeRun | ||
} | ||
return thisGet(`flow-node-runs/${nodeRun.id}`) | ||
}, | ||
) | ||
const flowNodeRuns = await Promise.all([...flowNodeRunFetches]) | ||
updateFlowNodeRuns(flowNodeRuns) | ||
} | ||
return new Promise((resolve, reject) => { | ||
function onUpdate() { | ||
options.onUpdate && options.onUpdate(flowRun) | ||
} | ||
async function onSuccess() { | ||
await completeFlowRunNodes() | ||
options.onSuccess && options.onSuccess(flowRun) | ||
resolve(flowRun) | ||
cleanup() | ||
} | ||
async function onFailure() { | ||
await completeFlowRunNodes() | ||
options.onFailure && options.onFailure(flowRun) | ||
reject(flowRun) | ||
cleanup() | ||
} | ||
/* POLLING */ | ||
checkFlowNodeRunsInterval = setInterval(async () => { | ||
const flowNodeRunsNext = await this.get( | ||
`flow-node-runs?filter[flowRunId]=${flowRunId}`, | ||
) | ||
updateFlowNodeRuns(flowNodeRunsNext) | ||
}, 1000) | ||
checkFlowRunInterval = setInterval(async () => { | ||
const flowRunLatest = await thisGet(`flow-runs/${flowRunId}`) | ||
updateFlowRun(flowRunLatest) | ||
switch (flowRunLatest.state) { | ||
case FlowRunState.COMPLETED: | ||
await onSuccess() | ||
break | ||
case FlowRunState.FAILED: | ||
await onFailure() | ||
break | ||
default: | ||
onUpdate() | ||
} | ||
}, 1000) | ||
/* PUSHER */ | ||
}) | ||
} | ||
public async getFlowNodeRunOutput(flowNodeRunId: string) { | ||
return this.get(`flow-node-runs/${flowNodeRunId}/output`) | ||
} | ||
public async getFlowRunOutput(flowRun: any): Promise<any> { | ||
const latestNodeRun = flowRun.nodeRuns | ||
// ids are created by MongoDB and are sequential | ||
.sort((r1: any, r2: any) => (r1.id > r2.id ? 1 : -1)) | ||
.pop() | ||
if (latestNodeRun) { | ||
return this.getFlowNodeRunOutput(latestNodeRun.id) | ||
} else { | ||
return undefined | ||
} | ||
} | ||
private getEmbedUri(page: string, params?: any) { | ||
@@ -187,2 +304,8 @@ const embedUrl = new URL(`${this.uiUri}/embed/${page}`) | ||
export interface RunFlowOptions { | ||
onSuccess?: (...args: any) => void | ||
onFailure?: (...args: any) => void | ||
onUpdate?: (...args: any) => void | ||
} | ||
export interface NewConnectionOptions { | ||
@@ -189,0 +312,0 @@ integratedAppKey: string |
287398
20
3444
4
+ Addedpusher-js@^7.0.3
+ Added@types/express-serve-static-core@4.17.28(transitive)
+ Added@types/node@14.18.63(transitive)
+ Added@types/qs@6.9.18(transitive)
+ Added@types/range-parser@1.2.7(transitive)
+ Addedpusher-js@7.6.0(transitive)
+ Addedtweetnacl@1.0.3(transitive)