@ukiahinsure/a2ui-react-adapter 0.1.21 → 0.1.23
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.
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as A2UIClientAdapter, a as A2UISurfaceMetadata, b as A2UISessionController, c as A2UIRoomLike } from './session-
|
|
2
|
-
export { d as A2UIActionDeliveryStatus, e as A2UIActionResult, f as A2UIActionState, g as A2UICapabilityEnvelope, h as A2UIClientActionEnvelope, i as A2UIClientAdapterOptions, j as A2UIClientErrorEnvelope, k as A2UIClientErrorEvent, l as A2UIEditingSnapshot, m as A2UIFieldControl, n as A2UIFieldDescriptor, o as A2UIFieldInteractionField, p as A2UIFieldInteractionGroup, q as A2UIFieldUpdateEvent, r as A2UIFieldValue, s as A2UIPendingAction, t as A2UIRendererActionEvent, u as A2UIServerEnvelope, v as A2UISessionControllerOptions, w as A2UISessionSnapshot, x as A2UISessionStatus, y as A2UIStreamParticipant, z as A2UISurfaceStructure, B as A2UITabDescriptor, C as A2UITrustedServerParticipant, D as A2UI_CAPABILITIES_TOPIC, E as A2UI_CLIENT_TOPIC, F as A2UI_PROTOCOL_VERSION, G as A2UI_SERVER_TOPIC, H as AckEnvelope, I as AckFieldError, J as AdapterSurface, K as CLIENT_ACTIONS, L as CLIENT_ERROR_CODES, M as ClientAction, N as ClientErrorCode, O as ENVELOPE_VERSION, P as MAX_ENVELOPE_BYTES, Q as ParticipantRole, S as SectionNavigation, R as SnapshotEnvelope, T as SurfaceUpdateEnvelope } from './session-
|
|
1
|
+
import { A as A2UIClientAdapter, a as A2UISurfaceMetadata, b as A2UISessionController, c as A2UIRoomLike } from './session-BU8eDAkA.js';
|
|
2
|
+
export { d as A2UIActionDeliveryStatus, e as A2UIActionResult, f as A2UIActionState, g as A2UICapabilityEnvelope, h as A2UIClientActionEnvelope, i as A2UIClientAdapterOptions, j as A2UIClientErrorEnvelope, k as A2UIClientErrorEvent, l as A2UIEditingSnapshot, m as A2UIFieldControl, n as A2UIFieldDescriptor, o as A2UIFieldInteractionField, p as A2UIFieldInteractionGroup, q as A2UIFieldUpdateEvent, r as A2UIFieldValue, s as A2UIPendingAction, t as A2UIRendererActionEvent, u as A2UIServerEnvelope, v as A2UISessionControllerOptions, w as A2UISessionSnapshot, x as A2UISessionStatus, y as A2UIStreamParticipant, z as A2UISurfaceStructure, B as A2UITabDescriptor, C as A2UITrustedServerParticipant, D as A2UI_CAPABILITIES_TOPIC, E as A2UI_CLIENT_TOPIC, F as A2UI_PROTOCOL_VERSION, G as A2UI_SERVER_TOPIC, H as AckEnvelope, I as AckFieldError, J as AdapterSurface, K as CLIENT_ACTIONS, L as CLIENT_ERROR_CODES, M as ClientAction, N as ClientErrorCode, O as ENVELOPE_VERSION, P as MAX_ENVELOPE_BYTES, Q as ParticipantRole, S as SectionNavigation, R as SnapshotEnvelope, T as SurfaceUpdateEnvelope } from './session-BU8eDAkA.js';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
/** Accessible host around the official A2UI v0.9.1 React surface. */
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,69 @@ var HospitalChoice = createComponentImplementation(ChoicePickerApi, ({ props, co
|
|
|
55
55
|
import { useId as useId2, useLayoutEffect, useRef, useState } from "react";
|
|
56
56
|
import { createComponentImplementation as createComponentImplementation2 } from "@a2ui/react/v0_9";
|
|
57
57
|
import { DateTimeInputApi } from "@a2ui/web_core/v0_9/basic_catalog";
|
|
58
|
+
|
|
59
|
+
// src/fieldLabel.ts
|
|
60
|
+
var ACRONYMS = {
|
|
61
|
+
aep: "AEP",
|
|
62
|
+
champva: "CHAMPVA",
|
|
63
|
+
dob: "DOB",
|
|
64
|
+
hmo: "HMO",
|
|
65
|
+
id: "ID",
|
|
66
|
+
iep: "IEP",
|
|
67
|
+
lis: "LIS",
|
|
68
|
+
ma: "MA",
|
|
69
|
+
mapd: "MAPD",
|
|
70
|
+
mbi: "MBI",
|
|
71
|
+
npi: "NPI",
|
|
72
|
+
oep: "OEP",
|
|
73
|
+
pcp: "PCP",
|
|
74
|
+
pdp: "PDP",
|
|
75
|
+
ppo: "PPO",
|
|
76
|
+
sep: "SEP",
|
|
77
|
+
snp: "SNP",
|
|
78
|
+
ssn: "SSN",
|
|
79
|
+
tricare: "TRICARE",
|
|
80
|
+
url: "URL",
|
|
81
|
+
us: "US",
|
|
82
|
+
va: "VA",
|
|
83
|
+
zip: "ZIP"
|
|
84
|
+
};
|
|
85
|
+
var MINOR_WORDS = /* @__PURE__ */ new Set([
|
|
86
|
+
"a",
|
|
87
|
+
"an",
|
|
88
|
+
"and",
|
|
89
|
+
"for",
|
|
90
|
+
"in",
|
|
91
|
+
"of",
|
|
92
|
+
"on",
|
|
93
|
+
"or",
|
|
94
|
+
"the",
|
|
95
|
+
"to",
|
|
96
|
+
"with"
|
|
97
|
+
]);
|
|
98
|
+
function displayFieldLabel(field) {
|
|
99
|
+
const words = field.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[\s_-]+/).filter(Boolean);
|
|
100
|
+
return words.map((word, index) => displayFieldLabelWord(word, index, words[index - 1])).join(" ");
|
|
101
|
+
}
|
|
102
|
+
function readableLabel(label) {
|
|
103
|
+
return /^[a-z][a-z0-9]*(_[a-z0-9]+)+$/.test(label) ? displayFieldLabel(label) : label;
|
|
104
|
+
}
|
|
105
|
+
function displayFieldLabelWord(word, index, previous) {
|
|
106
|
+
const lower = word.toLowerCase();
|
|
107
|
+
if (previous?.toLowerCase() === "part" && /^[a-d]$/.test(lower)) {
|
|
108
|
+
return lower.toUpperCase();
|
|
109
|
+
}
|
|
110
|
+
const acronym = ACRONYMS[lower];
|
|
111
|
+
if (acronym !== void 0) {
|
|
112
|
+
return acronym;
|
|
113
|
+
}
|
|
114
|
+
if (index > 0 && MINOR_WORDS.has(lower)) {
|
|
115
|
+
return lower;
|
|
116
|
+
}
|
|
117
|
+
return lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/DateTimeInput.tsx
|
|
58
121
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
59
122
|
var inputStyle = {
|
|
60
123
|
backgroundColor: "var(--a2ui-datetimeinput-background, var(--a2ui-color-input, #fff))",
|
|
@@ -167,7 +230,7 @@ function DateOnlyInput(props) {
|
|
|
167
230
|
"button",
|
|
168
231
|
{
|
|
169
232
|
type: "button",
|
|
170
|
-
"aria-label": `Choose ${props.label
|
|
233
|
+
"aria-label": `Choose ${props.label ? readableLabel(props.label) : "date"} from calendar`,
|
|
171
234
|
style: inputStyle,
|
|
172
235
|
onClick: () => openPicker(pickerRef.current, () => setPickerOpen(true)),
|
|
173
236
|
children: "\u25A6"
|
|
@@ -178,7 +241,7 @@ function DateOnlyInput(props) {
|
|
|
178
241
|
{
|
|
179
242
|
ref: pickerRef,
|
|
180
243
|
type: "date",
|
|
181
|
-
"aria-label": `${props.label
|
|
244
|
+
"aria-label": `${props.label ? readableLabel(props.label) : "Date"} calendar`,
|
|
182
245
|
tabIndex: pickerOpen ? 0 : -1,
|
|
183
246
|
"aria-hidden": !pickerOpen,
|
|
184
247
|
"data-a2ui-calendar-input": "true",
|
|
@@ -2665,6 +2728,21 @@ function formatFieldLabels(root) {
|
|
|
2665
2728
|
originals.set(element, element.textContent ?? "");
|
|
2666
2729
|
element.textContent = displayFieldLabel(field);
|
|
2667
2730
|
}
|
|
2731
|
+
const fields = new Set(
|
|
2732
|
+
[...root.querySelectorAll("[data-a2ui-field]")].map((control) => control.dataset.a2uiField).filter((field) => field !== void 0)
|
|
2733
|
+
);
|
|
2734
|
+
for (const element of root.querySelectorAll("*")) {
|
|
2735
|
+
if (element.childElementCount !== 0 || originals.has(element)) {
|
|
2736
|
+
continue;
|
|
2737
|
+
}
|
|
2738
|
+
const text = element.textContent ?? "";
|
|
2739
|
+
const match = /^(\s*)([A-Za-z][A-Za-z0-9_]*)(\s+\S[\s\S]*)$/.exec(text);
|
|
2740
|
+
if (match === null || !fields.has(match[2]) || !match[2].includes("_")) {
|
|
2741
|
+
continue;
|
|
2742
|
+
}
|
|
2743
|
+
originals.set(element, text);
|
|
2744
|
+
element.textContent = `${match[1]}${displayFieldLabel(match[2])}${match[3]}`;
|
|
2745
|
+
}
|
|
2668
2746
|
return () => {
|
|
2669
2747
|
for (const [label, text] of originals) {
|
|
2670
2748
|
label.textContent = text;
|
|
@@ -3355,28 +3433,6 @@ function labelElementForControl(root, control) {
|
|
|
3355
3433
|
const label = root.ownerDocument.getElementById(labelledBy);
|
|
3356
3434
|
return label instanceof HTMLElement && root.contains(label) ? label : void 0;
|
|
3357
3435
|
}
|
|
3358
|
-
function displayFieldLabel(field) {
|
|
3359
|
-
const words = field.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[\s_-]+/).filter(Boolean);
|
|
3360
|
-
return words.map((word, index) => displayFieldLabelWord(word, index)).join(" ");
|
|
3361
|
-
}
|
|
3362
|
-
function displayFieldLabelWord(word, index) {
|
|
3363
|
-
const lower = word.toLowerCase();
|
|
3364
|
-
const acronyms = {
|
|
3365
|
-
dob: "DOB",
|
|
3366
|
-
id: "ID",
|
|
3367
|
-
ssn: "SSN",
|
|
3368
|
-
url: "URL",
|
|
3369
|
-
us: "US",
|
|
3370
|
-
zip: "ZIP"
|
|
3371
|
-
};
|
|
3372
|
-
if (lower in acronyms) {
|
|
3373
|
-
return acronyms[lower];
|
|
3374
|
-
}
|
|
3375
|
-
if (index > 0 && ["a", "an", "and", "for", "in", "of", "on", "or", "the", "to", "with"].includes(lower)) {
|
|
3376
|
-
return lower;
|
|
3377
|
-
}
|
|
3378
|
-
return lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
3379
|
-
}
|
|
3380
3436
|
function cssString(value) {
|
|
3381
3437
|
return globalThis.CSS?.escape?.(value) ?? value.replace(/["\\]/g, "\\$&");
|
|
3382
3438
|
}
|
|
@@ -3598,6 +3654,7 @@ import { A2uiMessageListSchema as A2uiMessageListSchema2 } from "@a2ui/web_core/
|
|
|
3598
3654
|
|
|
3599
3655
|
// src/actions.ts
|
|
3600
3656
|
var DEFAULT_ACK_TIMEOUT_MS = 1e4;
|
|
3657
|
+
var MIN_STALL_MS = 2e4;
|
|
3601
3658
|
var SAFE_DETAIL = /^[A-Za-z0-9_.:-]{1,96}$/;
|
|
3602
3659
|
var MAX_IDENTIFIER_LENGTH = 256;
|
|
3603
3660
|
var EMPTY_ACTION_STATE = {
|
|
@@ -3901,11 +3958,25 @@ var A2UIClientActionBridge = class {
|
|
|
3901
3958
|
pending.timeoutId = void 0;
|
|
3902
3959
|
pending.deliveryStatus = "retryable";
|
|
3903
3960
|
this.#notify();
|
|
3961
|
+
this.#watchForStall(pending, generation);
|
|
3904
3962
|
}
|
|
3905
3963
|
}, this.#ackTimeoutMs());
|
|
3906
3964
|
this.#notify();
|
|
3907
3965
|
});
|
|
3908
3966
|
}
|
|
3967
|
+
/** A retried action that times out again is stalled; so is one left unretried. */
|
|
3968
|
+
#watchForStall(pending, generation) {
|
|
3969
|
+
if (pending.attemptCount >= 2) {
|
|
3970
|
+
this.#options.onStalled?.();
|
|
3971
|
+
return;
|
|
3972
|
+
}
|
|
3973
|
+
pending.timeoutId = globalThis.setTimeout(() => {
|
|
3974
|
+
if (this.#isCurrent(pending, generation) && pending.deliveryStatus === "retryable") {
|
|
3975
|
+
pending.timeoutId = void 0;
|
|
3976
|
+
this.#options.onStalled?.();
|
|
3977
|
+
}
|
|
3978
|
+
}, Math.max(this.#ackTimeoutMs() * 2, MIN_STALL_MS));
|
|
3979
|
+
}
|
|
3909
3980
|
#enqueue(operation) {
|
|
3910
3981
|
this.#publishQueue = this.#publishQueue.then(operation).catch(() => void 0);
|
|
3911
3982
|
}
|
|
@@ -4173,7 +4244,8 @@ var A2UISessionController = class {
|
|
|
4173
4244
|
reportClientError: (errorCode, surfaceId, detail) => this.#adapter.reportClientError(errorCode, surfaceId, detail),
|
|
4174
4245
|
onStateChange: (actions) => this.#handleActionStateChange(actions),
|
|
4175
4246
|
participantRole: this.#participantRole,
|
|
4176
|
-
ackTimeoutMs: options.actionAckTimeoutMs
|
|
4247
|
+
ackTimeoutMs: options.actionAckTimeoutMs,
|
|
4248
|
+
onStalled: () => this.resync()
|
|
4177
4249
|
});
|
|
4178
4250
|
}
|
|
4179
4251
|
get status() {
|
|
@@ -4189,6 +4261,18 @@ var A2UISessionController = class {
|
|
|
4189
4261
|
return this.#sessionSnapshot.actions;
|
|
4190
4262
|
}
|
|
4191
4263
|
/** Retry one or every delivery-failed/timed-out request with its original id. */
|
|
4264
|
+
/**
|
|
4265
|
+
* Drop pending actions and request an authoritative snapshot, as after a
|
|
4266
|
+
* reconnect. Used when an action is never acknowledged: the server's state
|
|
4267
|
+
* is the truth, and the form must not stay locked waiting for it.
|
|
4268
|
+
*/
|
|
4269
|
+
resync() {
|
|
4270
|
+
if (this.#closed || this.status !== "connected" || this.restoring) {
|
|
4271
|
+
return;
|
|
4272
|
+
}
|
|
4273
|
+
this.#actionBridge.discardPending();
|
|
4274
|
+
void this.#beginReconnectRestore();
|
|
4275
|
+
}
|
|
4192
4276
|
retryPendingAction(requestId) {
|
|
4193
4277
|
return this.#actionBridge.retryPendingAction(requestId);
|
|
4194
4278
|
}
|