Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 26 additions & 29 deletions e2e/davinci-app/components/polling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,51 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
import type { PollingCollector, Poller, Updater } from '@forgerock/davinci-client/types';
import type {
InternalErrorResponse,
NodeStates,
PollingCollector,
Poller,
} from '@forgerock/davinci-client/types';

function isInternalErrorResponse(
value: NodeStates | InternalErrorResponse,
): value is InternalErrorResponse {
return 'type' in value && value.type === 'internal_error';
}

export default function pollingComponent(
formEl: HTMLFormElement,
collector: PollingCollector,
poll: Poller,
updater: Updater<PollingCollector>,
submitForm: () => Promise<void>,
onNode: (node: NodeStates) => void,
) {
const button = document.createElement('button');
button.type = 'button';
button.value = collector.output.key;
button.innerHTML = 'Start polling';
button.textContent = 'Start polling';
formEl.appendChild(button);

const controller = new AbortController();

button.onclick = async () => {
button.disabled = true;

const p = document.createElement('p');
p.innerText = 'Polling...';
formEl?.appendChild(p);
const status = document.createElement('p');
status.textContent = 'Polling...';
formEl.appendChild(status);

const status = await poll();
if (typeof status !== 'string' && 'error' in status) {
console.error(status.error?.message);
const result = await poll({ signal: controller.signal });

if (isInternalErrorResponse(result)) {
console.error(result.error?.message);
const errEl = document.createElement('p');
errEl.innerText = 'Polling error: ' + status.error?.message;
formEl?.appendChild(errEl);
errEl.textContent = 'Polling error: ' + result.error?.message;
formEl.appendChild(errEl);
button.disabled = false;
return;
}

const result = updater(status);
if (result && 'error' in result) {
console.error(result.error.message);

const errEl = document.createElement('p');
errEl.innerText = 'Polling error: ' + result.error.message;
formEl?.appendChild(errEl);
return;
}

const resultEl = document.createElement('p');
resultEl.innerText = 'Polling result: ' + JSON.stringify(status, null, 2);
formEl?.appendChild(resultEl);

await submitForm();

button.disabled = false;
onNode(result);
};
}
6 changes: 4 additions & 2 deletions e2e/davinci-app/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,10 @@ const urlParams = new URLSearchParams(window.location.search);
formEl, // You can ignore this; it's just for rendering
collector, // This is the plain object of the collector
davinciClient.poll(collector), // Returns a poll function
davinciClient.update(collector), // Returns an update function for this collector
submitForm,
(node) => {
if (node.status === 'success') renderComplete();
else renderForm();
},
);
} else if (collector.type === 'FlowCollector') {
flowLinkComponent(
Expand Down
12 changes: 12 additions & 0 deletions e2e/davinci-app/server-configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,16 @@ export const serverConfigs: Record<string, DaVinciConfig> = {
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration',
},
},
/**
* Polling
*/
'ca0e8ba6-ad9f-4354-a778-d47fe8357ace': {
clientId: 'ca0e8ba6-ad9f-4354-a778-d47fe8357ace',
redirectUri: window.location.origin,
scope: 'openid profile email name revoke',
serverConfig: {
wellknown:
'https://auth.pingone.ca/02fb4743-189a-4bc7-9d6c-a919edfe6447/as/.well-known/openid-configuration',
},
},
};
16 changes: 9 additions & 7 deletions packages/davinci-client/api-report/davinci-client.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,13 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
resume: (input: {
continueToken: string;
}) => Promise<InternalErrorResponse | NodeStates>;
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode>;
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<ContinueNode | StartNode | ErrorNode | FailureNode | SuccessNode>;
update: <T extends SingleValueCollectors | MultiSelectCollector | ObjectValueCollectors | AutoCollectors>(collector: T) => Updater<T>;
validate: (collector: SingleValueCollectors | ObjectValueCollectors | MultiValueCollectors | AutoCollectors) => Validator;
poll: (collector: PollingCollector) => Poller;
getClient: () => {
status: "start";
} | {
action: string;
collectors: Collectors[];
description?: string;
Expand All @@ -254,8 +256,6 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
status: "error";
} | {
status: "failure";
} | {
status: "start";
} | {
authorization?: {
code?: string;
Expand All @@ -266,7 +266,7 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
getCollectors: () => Collectors[];
getError: () => DaVinciError | null;
getErrorCollectors: () => CollectorErrors[];
getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode;
getNode: () => ContinueNode | StartNode | ErrorNode | FailureNode | SuccessNode;
getServer: () => {
_links?: Links;
id?: string;
Expand All @@ -275,6 +275,8 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
href?: string;
eventName?: string;
status: "continue";
} | {
status: "start";
} | {
_links?: Links;
eventName?: string;
Expand All @@ -290,8 +292,6 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
interactionId?: string;
interactionToken?: string;
status: "failure";
} | {
status: "start";
} | {
_links?: Links;
eventName?: string;
Expand Down Expand Up @@ -1324,7 +1324,9 @@ export interface PhoneNumberOutputValue {
}

// @public (undocumented)
export type Poller = () => Promise<PollingStatus | InternalErrorResponse>;
export type Poller = (options?: {
signal?: AbortSignal;
}) => Promise<NodeStates | InternalErrorResponse>;

// @public (undocumented)
export type PollingCollector = AutoCollector<'SingleValueAutoCollector', 'PollingCollector', string, PollingOutputValue>;
Expand Down
16 changes: 9 additions & 7 deletions packages/davinci-client/api-report/davinci-client.types.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,13 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
resume: (input: {
continueToken: string;
}) => Promise<InternalErrorResponse | NodeStates>;
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode>;
start: <QueryParams extends OutgoingQueryParams = OutgoingQueryParams>(options?: StartOptions<QueryParams> | undefined) => Promise<ContinueNode | StartNode | ErrorNode | FailureNode | SuccessNode>;
update: <T extends SingleValueCollectors | MultiSelectCollector | ObjectValueCollectors | AutoCollectors>(collector: T) => Updater<T>;
validate: (collector: SingleValueCollectors | ObjectValueCollectors | MultiValueCollectors | AutoCollectors) => Validator;
poll: (collector: PollingCollector) => Poller;
getClient: () => {
status: "start";
} | {
action: string;
collectors: Collectors[];
description?: string;
Expand All @@ -254,8 +256,6 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
status: "error";
} | {
status: "failure";
} | {
status: "start";
} | {
authorization?: {
code?: string;
Expand All @@ -266,7 +266,7 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
getCollectors: () => Collectors[];
getError: () => DaVinciError | null;
getErrorCollectors: () => CollectorErrors[];
getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode;
getNode: () => ContinueNode | StartNode | ErrorNode | FailureNode | SuccessNode;
getServer: () => {
_links?: Links;
id?: string;
Expand All @@ -275,6 +275,8 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
href?: string;
eventName?: string;
status: "continue";
} | {
status: "start";
} | {
_links?: Links;
eventName?: string;
Expand All @@ -290,8 +292,6 @@ export function davinci<ActionType extends ActionTypes = ActionTypes>(input: {
interactionId?: string;
interactionToken?: string;
status: "failure";
} | {
status: "start";
} | {
_links?: Links;
eventName?: string;
Expand Down Expand Up @@ -1321,7 +1321,9 @@ export interface PhoneNumberOutputValue {
}

// @public (undocumented)
export type Poller = () => Promise<PollingStatus | InternalErrorResponse>;
export type Poller = (options?: {
signal?: AbortSignal;
}) => Promise<NodeStates | InternalErrorResponse>;

// @public (undocumented)
export type PollingCollector = AutoCollector<'SingleValueAutoCollector', 'PollingCollector', string, PollingOutputValue>;
Expand Down
Loading
Loading