@domino-sdk/relay 1.7.0 → 1.10.0

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 (45) hide show
  1. package/dist/action-9Xl0StBg.d.ts +33 -0
  2. package/dist/{activity-Br6vyYze.d.ts → activity-C0O3g7VJ.d.ts} +9 -9
  3. package/dist/authoring.d.ts +12 -12
  4. package/dist/authoring.js +3 -3
  5. package/dist/{automatic-outcomes-C1Q9LrDb.d.ts → automatic-outcomes-kPIDv6X_.d.ts} +1 -1
  6. package/dist/avatar.d.ts +2 -2
  7. package/dist/browser.d.ts +9 -8
  8. package/dist/browser.js +8 -6
  9. package/dist/{capability-error-Bv996M-h.d.ts → capability-error-ty3SqD_b.d.ts} +1 -1
  10. package/dist/{chunk-KGJSKGKI.js → chunk-23JUD56J.js} +1119 -910
  11. package/dist/{chunk-ZOUEEK5L.js → chunk-7BRHUUVB.js} +83 -26
  12. package/dist/{chunk-C25TDFHN.js → chunk-BKLGWPPD.js} +48 -37
  13. package/dist/{chunk-6ON4RMEN.js → chunk-BUXNTVER.js} +1 -1
  14. package/dist/{chunk-BFZHJA2B.js → chunk-GEPSEVQO.js} +2 -2
  15. package/dist/chunk-GFAFH7XR.js +98 -0
  16. package/dist/{chunk-6RBF3UDA.js → chunk-GPS546KR.js} +232 -7
  17. package/dist/{chunk-5ECM6AWV.js → chunk-MMWTHVXW.js} +3 -3
  18. package/dist/chunk-N2HXMTVA.js +13 -0
  19. package/dist/{chunk-23QJ7WH4.js → chunk-QL77V77D.js} +1 -1
  20. package/dist/{chunk-GMPPLZKH.js → chunk-UIR6NSYZ.js} +243 -228
  21. package/dist/{chunk-JW4G3SY5.js → chunk-WRBPLXVP.js} +60 -47
  22. package/dist/{client-pfml_XAa.d.ts → client-Yq11HA_f.d.ts} +64 -43
  23. package/dist/{groups-BpWEqaPn.d.ts → groups-BK8ts2yK.d.ts} +94 -6
  24. package/dist/{images-BaKYd0fl.d.ts → images-aw6W7vFZ.d.ts} +2 -2
  25. package/dist/index.d.ts +10 -9
  26. package/dist/index.js +10 -5
  27. package/dist/internal.d.ts +3 -3
  28. package/dist/internal.js +5 -5
  29. package/dist/{offers-CYtal8jO.d.ts → offers-C2FANzrG.d.ts} +3 -3
  30. package/dist/{pages-CixTNnF4.d.ts → pages-D00JDZB-.d.ts} +70 -39
  31. package/dist/portal-proxy.js +8 -2
  32. package/dist/react/index.d.ts +203 -19
  33. package/dist/react/index.js +256 -113
  34. package/dist/{referral-reward-kinds-ClxAuCGx.d.ts → referral-reward-kinds-M3f0PdiR.d.ts} +2 -2
  35. package/dist/{schema-CQydLqw4.d.ts → schema-DEM8y8Fm.d.ts} +16 -16
  36. package/dist/schema.d.ts +11239 -13
  37. package/dist/schema.js +38 -6
  38. package/dist/server/index.d.ts +43693 -52
  39. package/dist/server/index.js +465 -53
  40. package/dist/{sign-in-options-CtXUFV7E.d.ts → sign-in-options-Coim0G1u.d.ts} +3 -3
  41. package/dist/{submission-input-CLefHTrj.d.ts → submission-input-BbBJTVlT.d.ts} +3 -3
  42. package/dist/util.d-w9f9t3ua.d.ts +5 -0
  43. package/dist/{wallet-YssWxGg8.d.ts → wallet-CDyo-U4n.d.ts} +1 -1
  44. package/package.json +1 -1
  45. package/dist/{profiles-D2aFcOxu.d.ts → profiles-BHMVj0kM.d.ts} +5 -5
@@ -1,3 +1,7 @@
1
+ import {
2
+ createRelayAction,
3
+ withActionId
4
+ } from "./chunk-GFAFH7XR.js";
1
5
  import {
2
6
  collectionPassSchema,
3
7
  participantActivityQuerySchema,
@@ -12,7 +16,7 @@ import {
12
16
  questOutcomeQuerySchema,
13
17
  questOutcomeSchema,
14
18
  rewardDeliveriesSchema
15
- } from "./chunk-C25TDFHN.js";
19
+ } from "./chunk-BKLGWPPD.js";
16
20
  import {
17
21
  AVATAR_UPLOAD_LIMIT,
18
22
  RelayError,
@@ -23,7 +27,7 @@ import {
23
27
  engagementPageQuerySchema,
24
28
  engagementPageSchema,
25
29
  isRelayError,
26
- leaderboardDefinitionSchema,
30
+ leaderboardDefinitionResponseSchema,
27
31
  leaderboardPageSchema,
28
32
  leaderboardPlacementSchema,
29
33
  leaderboardQuerySchema,
@@ -51,7 +55,7 @@ import {
51
55
  walletSignInNetworksSchema,
52
56
  walletSignatureSchema,
53
57
  walletUnlinkInputSchema
54
- } from "./chunk-GMPPLZKH.js";
58
+ } from "./chunk-UIR6NSYZ.js";
55
59
  import {
56
60
  PARTICIPANT_TIMEOUT,
57
61
  lifetime,
@@ -59,13 +63,16 @@ import {
59
63
  retrying,
60
64
  validTimeout
61
65
  } from "./chunk-6QJ3LADK.js";
66
+ import {
67
+ clientIdentity
68
+ } from "./chunk-N2HXMTVA.js";
62
69
  import {
63
70
  exchangeResultSchema,
64
71
  exchangeSchema,
65
72
  memberSummarySchema,
66
73
  participantSessionSchema,
67
74
  sessionMember
68
- } from "./chunk-6ON4RMEN.js";
75
+ } from "./chunk-BUXNTVER.js";
69
76
  import {
70
77
  accountConnectionSchema,
71
78
  attemptSchema,
@@ -79,6 +86,7 @@ import {
79
86
  contentQualificationQuerySchema,
80
87
  evidenceSchema,
81
88
  identifier,
89
+ knownResponse,
82
90
  memberProgressSchema,
83
91
  missingPrerequisiteSchema,
84
92
  pageQuerySchema,
@@ -88,7 +96,7 @@ import {
88
96
  tieredRewardReferenceSchema,
89
97
  validateSubmissionValue,
90
98
  valueEvidenceSchema
91
- } from "./chunk-KGJSKGKI.js";
99
+ } from "./chunk-23JUD56J.js";
92
100
 
93
101
  // src/submissions.ts
94
102
  import { z } from "zod";
@@ -848,6 +856,7 @@ function relayClient(options) {
848
856
  async function send(path, call, life) {
849
857
  const method = methodOf(call);
850
858
  const headers = new Headers(call.headers);
859
+ headers.set("X-Domino-Client", clientIdentity());
851
860
  let body2 = call.body;
852
861
  if (options.token) {
853
862
  headers.set("Authorization", `Bearer ${options.token}`);
@@ -969,7 +978,7 @@ function relayClient(options) {
969
978
  } catch (error) {
970
979
  throw invalidResponse(response.status, call, error);
971
980
  }
972
- const parsed = schema.safeParse(value);
981
+ const parsed = knownResponse(schema).safeParse(value);
973
982
  if (!parsed.success) {
974
983
  throw invalidResponse(response.status, call, parsed.error);
975
984
  }
@@ -1070,6 +1079,32 @@ function relayClient(options) {
1070
1079
  const ok = z2.object({ ok: z2.literal(true) });
1071
1080
  const acknowledged = z2.object({ ok: z2.boolean() });
1072
1081
  return {
1082
+ /** Owns one action key across uncertain writes. Reuse the helper until a definite answer. */
1083
+ action: createRelayAction,
1084
+ /** A JSON call using an explicit tolerant response schema from `@domino-sdk/relay/schema`. */
1085
+ response: (path, schema, call = {}) => {
1086
+ const base = new URL(options.baseUrl, "http://response.invalid");
1087
+ const target = new URL(path, base);
1088
+ if (!path.startsWith("/v1/") || /[\\#]/.test(path) || /%2e|%2f|%5c/i.test(path.split("?")[0]) || target.origin !== base.origin || !target.pathname.startsWith("/v1/")) {
1089
+ throw clientError(
1090
+ "Response path must stay within /v1",
1091
+ RelayErrorCode.InvalidInput
1092
+ );
1093
+ }
1094
+ const requestCall = {
1095
+ method: call.method,
1096
+ json: call.input,
1097
+ operationId: call.operationId,
1098
+ replaySafe: call.replaySafe,
1099
+ headers: { "X-Domino-Response": "tolerant-v1" },
1100
+ options: call
1101
+ };
1102
+ return exchange(path, requestCall, async (response, life) => ({
1103
+ status: response.status,
1104
+ operationId: call.operationId,
1105
+ result: await read(response, schema, requestCall, life)
1106
+ }));
1107
+ },
1073
1108
  offers: {
1074
1109
  /** Offers available to this participant, including stock and per-member availability. */
1075
1110
  list: (requestOptions) => request("/v1/offers", z2.array(offerSchema), {
@@ -1103,7 +1138,7 @@ function relayClient(options) {
1103
1138
  { options: requestOptions }
1104
1139
  ),
1105
1140
  accept: async (value, requestOptions) => {
1106
- const body2 = parseInput(referralAcceptSchema, value);
1141
+ const body2 = parseInput(referralAcceptSchema, withActionId(value));
1107
1142
  return request("/v1/referrals/accept", ok, {
1108
1143
  json: body2,
1109
1144
  options: requestOptions,
@@ -1138,7 +1173,7 @@ function relayClient(options) {
1138
1173
  })
1139
1174
  },
1140
1175
  leaderboards: {
1141
- list: (requestOptions) => request("/v1/leaderboards", z2.array(leaderboardDefinitionSchema), {
1176
+ list: (requestOptions) => request("/v1/leaderboards", z2.array(leaderboardDefinitionResponseSchema), {
1142
1177
  options: requestOptions
1143
1178
  }),
1144
1179
  standings: async (board, query = {}, requestOptions) => request(
@@ -1174,10 +1209,15 @@ function relayClient(options) {
1174
1209
  * Changes the member's own name, avatar choice or visibility; omitted fields stay, and null
1175
1210
  * returns to the default.
1176
1211
  */
1177
- update: async (value, requestOptions) => request("/v1/me/profile", ownProfileSchema, {
1178
- json: parseInput(profileUpdateSchema, value),
1179
- options: requestOptions
1180
- }),
1212
+ update: async (value, requestOptions) => {
1213
+ const { actionId, ...profile } = value;
1214
+ return request("/v1/me/profile", ownProfileSchema, {
1215
+ json: parseInput(profileUpdateSchema, profile),
1216
+ options: requestOptions,
1217
+ operationId: parseInput(identifier, actionId ?? crypto.randomUUID()),
1218
+ replaySafe: false
1219
+ });
1220
+ },
1181
1221
  /**
1182
1222
  * Uploads a JPEG, PNG or WebP of at most 5 MB as the member's avatar. The server crops it to
1183
1223
  * a 512×512 WebP without metadata. The client never resends it: retrying with the same
@@ -1196,8 +1236,11 @@ function relayClient(options) {
1196
1236
  RelayErrorCode.InvalidInput
1197
1237
  );
1198
1238
  }
1199
- const { uploadId, ...rest } = requestOptions;
1200
- const operationId = parseInput(identifier, uploadId ?? crypto.randomUUID());
1239
+ const { actionId, uploadId, ...rest } = requestOptions;
1240
+ const operationId = parseInput(
1241
+ identifier,
1242
+ actionId ?? uploadId ?? crypto.randomUUID()
1243
+ );
1201
1244
  return request("/v1/me/profile/avatar", ownProfileSchema, {
1202
1245
  method: "POST",
1203
1246
  body: file,
@@ -1251,7 +1294,7 @@ function relayClient(options) {
1251
1294
  * on a quest that counts from enrollment. Enrolling again returns the first enrollment.
1252
1295
  */
1253
1296
  enroll: async (value, requestOptions) => {
1254
- const body2 = parseInput(questEnrollmentInputSchema, value);
1297
+ const body2 = parseInput(questEnrollmentInputSchema, withActionId(value));
1255
1298
  return request("/v1/quests/enrollments", questEnrollmentSchema, {
1256
1299
  json: body2,
1257
1300
  options: requestOptions,
@@ -1265,7 +1308,7 @@ function relayClient(options) {
1265
1308
  * with a `RelayError` whose code is that rule's skip code.
1266
1309
  */
1267
1310
  claim: async (value, requestOptions) => {
1268
- const body2 = parseInput(questClaimInputSchema, value);
1311
+ const body2 = parseInput(questClaimInputSchema, withActionId(value));
1269
1312
  return request("/v1/quests/claims", questOutcomeSchema, {
1270
1313
  json: body2,
1271
1314
  options: requestOptions,
@@ -1335,7 +1378,7 @@ function relayClient(options) {
1335
1378
  campaigns: {
1336
1379
  /** Enrolls the signed-in member once in every quest of a campaign that requires it. */
1337
1380
  enroll: async (value, requestOptions) => {
1338
- const body2 = parseInput(campaignEnrollmentInputSchema, value);
1381
+ const body2 = parseInput(campaignEnrollmentInputSchema, withActionId(value));
1339
1382
  return request("/v1/campaigns/enrollments", campaignEnrollmentSchema, {
1340
1383
  json: body2,
1341
1384
  options: requestOptions,
@@ -1344,7 +1387,7 @@ function relayClient(options) {
1344
1387
  },
1345
1388
  /** Pauses the signed-in member's campaign enrollment without erasing its history. */
1346
1389
  withdraw: async (value, requestOptions) => {
1347
- const body2 = parseInput(campaignWithdrawalInputSchema, value);
1390
+ const body2 = parseInput(campaignWithdrawalInputSchema, withActionId(value));
1348
1391
  return request(
1349
1392
  "/v1/campaigns/enrollments/withdraw",
1350
1393
  campaignEnrollmentSchema,
@@ -1624,20 +1667,34 @@ function relayClient(options) {
1624
1667
  },
1625
1668
  /** Claims a quest for the signed-in member. Quest controllers (`quests.open`) call this. */
1626
1669
  claim: async (value, requestOptions) => {
1627
- const claim = parseInput(submitSchema.omit({ member: true }), value);
1670
+ const claim = parseInput(
1671
+ submitSchema.omit({ member: true }),
1672
+ withActionId(value)
1673
+ );
1628
1674
  return request("/v1/me/attempts", attemptSchema, {
1629
1675
  json: claim,
1630
1676
  options: requestOptions,
1631
1677
  operationId: claim.actionId
1632
1678
  });
1633
1679
  },
1634
- /** Uploads a photo as the signed-in member's evidence. */
1635
- upload: (file, requestOptions) => request("/v1/me/evidence", evidenceSchema, {
1636
- method: "POST",
1637
- body: file,
1638
- headers: { "Content-Type": file.type },
1639
- options: requestOptions
1640
- })
1680
+ /** Uploads evidence with a generated key; reuse `actionId` and the same file to replay. */
1681
+ upload: (file, requestOptions = {}) => {
1682
+ const { actionId, uploadId, ...options2 } = requestOptions;
1683
+ const operationId = parseInput(
1684
+ identifier,
1685
+ actionId ?? uploadId ?? crypto.randomUUID()
1686
+ );
1687
+ return request("/v1/me/evidence", evidenceSchema, {
1688
+ method: "POST",
1689
+ body: file,
1690
+ headers: {
1691
+ "Content-Type": file.type,
1692
+ "X-Relay-Upload-ID": operationId
1693
+ },
1694
+ options: options2,
1695
+ operationId
1696
+ });
1697
+ }
1641
1698
  },
1642
1699
  evidence: {
1643
1700
  /**
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pointLedgerReferenceSchema
3
- } from "./chunk-GMPPLZKH.js";
3
+ } from "./chunk-UIR6NSYZ.js";
4
4
  import {
5
5
  authoringIdentityShape,
6
6
  entitlementSchema,
@@ -11,12 +11,13 @@ import {
11
11
  pickupSelectionSchema,
12
12
  prerequisiteSchema,
13
13
  publishedReleaseSchema,
14
+ responseShape,
14
15
  reviewModeSchema,
15
16
  settingsValuesSchema,
16
17
  storedQuestDescriptionSchema,
17
18
  storedReviewModeSchema,
18
19
  tieredRewardReferenceSchema
19
- } from "./chunk-KGJSKGKI.js";
20
+ } from "./chunk-23JUD56J.js";
20
21
 
21
22
  // src/participant-activity.ts
22
23
  import { z } from "zod";
@@ -154,22 +155,26 @@ var draftBase = z2.object({
154
155
  baseRevision: z2.number().int().nonnegative(),
155
156
  changes: questDraftChangesSchema
156
157
  });
157
- var questDraftSchema = z2.discriminatedUnion("status", [
158
- draftBase.extend({ status: z2.literal("draft") }),
159
- draftBase.extend({
160
- status: z2.literal("published"),
161
- releaseIds: z2.array(identifier)
158
+ var questDraftSchema = responseShape(
159
+ z2.discriminatedUnion("status", [
160
+ draftBase.extend({ status: z2.literal("draft") }),
161
+ draftBase.extend({
162
+ status: z2.literal("published"),
163
+ releaseIds: z2.array(identifier)
164
+ })
165
+ ])
166
+ );
167
+ var questCatalogSchema = responseShape(
168
+ z2.object({
169
+ revision: z2.number().int().nonnegative(),
170
+ types: z2.array(questTypeVersionSchema),
171
+ collections: z2.array(questCollectionSchema),
172
+ quests: z2.array(questInstanceSchema),
173
+ drafts: z2.array(questDraftSchema),
174
+ releases: z2.array(publishedReleaseSchema).default([]),
175
+ supportedInteractions: z2.array(interactionSchema)
162
176
  })
163
- ]);
164
- var questCatalogSchema = z2.object({
165
- revision: z2.number().int().nonnegative(),
166
- types: z2.array(questTypeVersionSchema),
167
- collections: z2.array(questCollectionSchema),
168
- quests: z2.array(questInstanceSchema),
169
- drafts: z2.array(questDraftSchema),
170
- releases: z2.array(publishedReleaseSchema).default([]),
171
- supportedInteractions: z2.array(interactionSchema)
172
- });
177
+ );
173
178
  var catalogDeploymentSchema = z2.object({
174
179
  expectedRevision: z2.number().int().nonnegative(),
175
180
  types: z2.array(
@@ -181,12 +186,14 @@ var catalogDeploymentSchema = z2.object({
181
186
  collections: z2.array(collectionSlotDeclarationSchema).max(50).default([]),
182
187
  supportedInteractions: z2.array(interactionSchema).min(1).optional()
183
188
  }).strict();
184
- var catalogDeploymentPreviewSchema = z2.object({
185
- revision: z2.number().int().nonnegative(),
186
- types: z2.array(questTypeVersionSchema),
187
- collections: z2.array(collectionSlotSchema),
188
- supportedInteractions: z2.array(interactionSchema)
189
- });
189
+ var catalogDeploymentPreviewSchema = responseShape(
190
+ z2.object({
191
+ revision: z2.number().int().nonnegative(),
192
+ types: z2.array(questTypeVersionSchema),
193
+ collections: z2.array(collectionSlotSchema),
194
+ supportedInteractions: z2.array(interactionSchema)
195
+ })
196
+ );
190
197
  var saveQuestDraftSchema = z2.object({
191
198
  id: identifier.optional(),
192
199
  actionId: identifier,
@@ -210,13 +217,13 @@ var questRewardViewSchema = z2.discriminatedUnion("kind", [
210
217
  }),
211
218
  z2.object({ kind: z2.literal("integration"), label: z2.string() })
212
219
  ]);
213
- var questViewSchema = memberProgressSchema.shape.quests.element.extend(
214
- {
220
+ var questViewSchema = responseShape(
221
+ memberProgressSchema.shape.quests.element.extend({
215
222
  release: identifier,
216
223
  interaction: interactionSchema,
217
224
  lifecycle: z2.enum(["active", "paused", "archived"]),
218
225
  rewards: z2.array(questRewardViewSchema)
219
- }
226
+ })
220
227
  );
221
228
  var collectionViewSchema = z2.object({
222
229
  key: identifier.optional(),
@@ -224,17 +231,21 @@ var collectionViewSchema = z2.object({
224
231
  title: z2.string(),
225
232
  quests: z2.array(questViewSchema)
226
233
  });
227
- var questExperienceSchema = z2.object({
228
- entitlements: z2.array(entitlementSchema).default([]),
229
- member: identifier,
230
- quests: z2.array(questViewSchema),
231
- collections: z2.array(collectionViewSchema)
232
- });
233
- var questPublicationPreviewSchema = z2.object({
234
- draft: questDraftSchema,
235
- releases: z2.array(publishedReleaseSchema),
236
- affectedCollections: z2.array(questCollectionSchema)
237
- });
234
+ var questExperienceSchema = responseShape(
235
+ z2.object({
236
+ entitlements: z2.array(entitlementSchema).default([]),
237
+ member: identifier,
238
+ quests: z2.array(questViewSchema),
239
+ collections: z2.array(collectionViewSchema)
240
+ })
241
+ );
242
+ var questPublicationPreviewSchema = responseShape(
243
+ z2.object({
244
+ draft: questDraftSchema,
245
+ releases: z2.array(publishedReleaseSchema),
246
+ affectedCollections: z2.array(questCollectionSchema)
247
+ })
248
+ );
238
249
  var allocateQuestSchema = z2.object({ actionId: identifier }).strict();
239
250
  var allocatedQuestSchema = z2.object({ id: identifier });
240
251
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  identifier
3
- } from "./chunk-KGJSKGKI.js";
3
+ } from "./chunk-23JUD56J.js";
4
4
 
5
5
  // src/auth.ts
6
6
  import { z } from "zod";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createRelayClient
3
- } from "./chunk-ZOUEEK5L.js";
3
+ } from "./chunk-7BRHUUVB.js";
4
4
  import {
5
5
  RelayErrorCode,
6
6
  asRelayError,
7
7
  clientError,
8
8
  cosmosChain
9
- } from "./chunk-GMPPLZKH.js";
9
+ } from "./chunk-UIR6NSYZ.js";
10
10
 
11
11
  // src/base58.ts
12
12
  var alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@@ -0,0 +1,98 @@
1
+ import {
2
+ RelayErrorCode,
3
+ clientError
4
+ } from "./chunk-UIR6NSYZ.js";
5
+ import {
6
+ isRequestError
7
+ } from "./chunk-NPGENI7K.js";
8
+
9
+ // src/action.ts
10
+ function withActionId(value) {
11
+ return { ...value, actionId: value.actionId ?? crypto.randomUUID() };
12
+ }
13
+ function createRelayAction() {
14
+ let pending;
15
+ let flight;
16
+ let error;
17
+ let retryAt = 0;
18
+ function send(write) {
19
+ pending = write;
20
+ const previousError = error;
21
+ flight = Promise.resolve().then(async () => {
22
+ const wait = retryAt - Date.now();
23
+ if (wait > 0) {
24
+ await new Promise((resolve) => setTimeout(resolve, wait));
25
+ }
26
+ return write.task(write.actionId);
27
+ }).then(
28
+ (value) => {
29
+ pending = void 0;
30
+ error = void 0;
31
+ return value;
32
+ },
33
+ (cause) => {
34
+ retryAt = Date.now() + (isRequestError(cause) ? cause.retryAfter ?? 0 : 0);
35
+ if (isRequestError(cause) && cause.uncertain) {
36
+ error = cause;
37
+ } else if (previousError) {
38
+ throw previousError;
39
+ } else {
40
+ pending = void 0;
41
+ }
42
+ throw cause;
43
+ }
44
+ ).finally(() => {
45
+ flight = void 0;
46
+ });
47
+ return flight;
48
+ }
49
+ function retry() {
50
+ if (flight) {
51
+ return flight;
52
+ }
53
+ if (!pending || !error || error.recovery !== "replay" || error.operationId !== pending.actionId) {
54
+ return Promise.reject(
55
+ error ?? clientError(
56
+ "There is no replay-safe action to retry",
57
+ RelayErrorCode.InvalidInput
58
+ )
59
+ );
60
+ }
61
+ return send(pending);
62
+ }
63
+ return {
64
+ get actionId() {
65
+ return pending?.actionId;
66
+ },
67
+ get busy() {
68
+ return flight !== void 0;
69
+ },
70
+ get error() {
71
+ return error;
72
+ },
73
+ run(task) {
74
+ if (flight) {
75
+ return flight;
76
+ }
77
+ if (pending) {
78
+ return retry();
79
+ }
80
+ return send({ actionId: crypto.randomUUID(), task });
81
+ },
82
+ retry,
83
+ settle() {
84
+ if (flight) {
85
+ return false;
86
+ }
87
+ pending = void 0;
88
+ error = void 0;
89
+ retryAt = 0;
90
+ return true;
91
+ }
92
+ };
93
+ }
94
+
95
+ export {
96
+ withActionId,
97
+ createRelayAction
98
+ };