@superbuilders/primer-tives 0.3.2 → 0.5.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.
- package/README.md +447 -150
- package/dist/choice-state.d.ts.map +1 -1
- package/dist/content.d.ts +7 -3
- package/dist/content.d.ts.map +1 -1
- package/dist/extended-text-state.d.ts.map +1 -1
- package/dist/feedback-state.d.ts +2 -2
- package/dist/feedback-state.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +298 -144
- package/dist/index.js.map +12 -12
- package/dist/match-state.d.ts.map +1 -1
- package/dist/order-state.d.ts +3 -10
- package/dist/order-state.d.ts.map +1 -1
- package/dist/pci-state.d.ts.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/text-entry-state.d.ts.map +1 -1
- package/dist/transport.d.ts +2 -2
- package/dist/transport.d.ts.map +1 -1
- package/dist/types.d.ts +61 -28
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
|
-
import * as
|
|
2
|
+
import * as errors10 from "@superbuilders/errors";
|
|
3
3
|
|
|
4
4
|
// src/errors.ts
|
|
5
5
|
import * as errors from "@superbuilders/errors";
|
|
@@ -131,7 +131,7 @@ function createTransport(tc) {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
// src/session.ts
|
|
134
|
-
import * as
|
|
134
|
+
import * as errors9 from "@superbuilders/errors";
|
|
135
135
|
|
|
136
136
|
// src/consumed.ts
|
|
137
137
|
function poisonToJSON() {
|
|
@@ -173,7 +173,45 @@ function validateChoiceSubmission(log, selectedKeys, options, maxChoices, minCho
|
|
|
173
173
|
return null;
|
|
174
174
|
}
|
|
175
175
|
function choiceState(ctx, stimulus, interaction, options, maxChoices, minChoices) {
|
|
176
|
-
let
|
|
176
|
+
let submitPending;
|
|
177
|
+
let submitKey;
|
|
178
|
+
let timeoutPending;
|
|
179
|
+
function beginSubmit(selectedKeys) {
|
|
180
|
+
const submission = { type: "choice", selectedKeys };
|
|
181
|
+
const key = JSON.stringify(submission);
|
|
182
|
+
if (timeoutPending) {
|
|
183
|
+
return Promise.resolve(ctx.errored(errors3.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
184
|
+
}
|
|
185
|
+
if (submitPending) {
|
|
186
|
+
if (submitKey === key) {
|
|
187
|
+
return submitPending;
|
|
188
|
+
}
|
|
189
|
+
return Promise.resolve(ctx.errored(errors3.wrap(ErrConflict, "cannot submit a different choice payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
190
|
+
}
|
|
191
|
+
const validationError = validateChoiceSubmission(ctx.log, selectedKeys, options, maxChoices, minChoices);
|
|
192
|
+
if (validationError) {
|
|
193
|
+
return Promise.resolve(ctx.errored(validationError, "interaction", { kind: "interaction", submission }));
|
|
194
|
+
}
|
|
195
|
+
submitKey = key;
|
|
196
|
+
submitPending = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
197
|
+
submitPending = undefined;
|
|
198
|
+
submitKey = undefined;
|
|
199
|
+
});
|
|
200
|
+
return submitPending;
|
|
201
|
+
}
|
|
202
|
+
function beginTimeout() {
|
|
203
|
+
const intent = { kind: "timeout" };
|
|
204
|
+
if (submitPending) {
|
|
205
|
+
return Promise.resolve(ctx.errored(errors3.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
206
|
+
}
|
|
207
|
+
if (timeoutPending) {
|
|
208
|
+
return timeoutPending;
|
|
209
|
+
}
|
|
210
|
+
timeoutPending = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
211
|
+
timeoutPending = undefined;
|
|
212
|
+
});
|
|
213
|
+
return timeoutPending;
|
|
214
|
+
}
|
|
177
215
|
return {
|
|
178
216
|
phase: "interaction",
|
|
179
217
|
kind: "choice",
|
|
@@ -182,27 +220,8 @@ function choiceState(ctx, stimulus, interaction, options, maxChoices, minChoices
|
|
|
182
220
|
options,
|
|
183
221
|
maxChoices,
|
|
184
222
|
minChoices,
|
|
185
|
-
submitChoice:
|
|
186
|
-
|
|
187
|
-
return pending;
|
|
188
|
-
}
|
|
189
|
-
const validationError = validateChoiceSubmission(ctx.log, selectedKeys, options, maxChoices, minChoices);
|
|
190
|
-
if (validationError) {
|
|
191
|
-
return Promise.resolve(ctx.errored(validationError, "interaction", {
|
|
192
|
-
kind: "interaction",
|
|
193
|
-
submission: { type: "choice", selectedKeys }
|
|
194
|
-
}));
|
|
195
|
-
}
|
|
196
|
-
pending = ctx.execute({ kind: "interaction", submission: { type: "choice", selectedKeys } }, "interaction");
|
|
197
|
-
return pending;
|
|
198
|
-
},
|
|
199
|
-
timeout: function timeout() {
|
|
200
|
-
if (pending) {
|
|
201
|
-
return pending;
|
|
202
|
-
}
|
|
203
|
-
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
204
|
-
return pending;
|
|
205
|
-
},
|
|
223
|
+
submitChoice: beginSubmit,
|
|
224
|
+
timeout: beginTimeout,
|
|
206
225
|
toJSON: poisonToJSON
|
|
207
226
|
};
|
|
208
227
|
}
|
|
@@ -222,66 +241,107 @@ function validateExtendedTextSubmission(log, values, minStrings, maxStrings) {
|
|
|
222
241
|
}
|
|
223
242
|
function extendedTextState(ctx, stimulus, interaction) {
|
|
224
243
|
if (interaction.cardinality === "single") {
|
|
225
|
-
let
|
|
244
|
+
let submitText = function(value) {
|
|
245
|
+
const submission = { type: "extended-text", values: [value] };
|
|
246
|
+
const key = JSON.stringify(submission);
|
|
247
|
+
if (timeoutPending2) {
|
|
248
|
+
return Promise.resolve(ctx.errored(errors4.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
249
|
+
}
|
|
250
|
+
if (submitPending2) {
|
|
251
|
+
if (submitKey2 === key) {
|
|
252
|
+
return submitPending2;
|
|
253
|
+
}
|
|
254
|
+
return Promise.resolve(ctx.errored(errors4.wrap(ErrConflict, "cannot submit a different extended-text payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
255
|
+
}
|
|
256
|
+
submitKey2 = key;
|
|
257
|
+
submitPending2 = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
258
|
+
submitPending2 = undefined;
|
|
259
|
+
submitKey2 = undefined;
|
|
260
|
+
});
|
|
261
|
+
return submitPending2;
|
|
262
|
+
}, timeout2 = function() {
|
|
263
|
+
const intent = { kind: "timeout" };
|
|
264
|
+
if (submitPending2) {
|
|
265
|
+
return Promise.resolve(ctx.errored(errors4.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
266
|
+
}
|
|
267
|
+
if (timeoutPending2) {
|
|
268
|
+
return timeoutPending2;
|
|
269
|
+
}
|
|
270
|
+
timeoutPending2 = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
271
|
+
timeoutPending2 = undefined;
|
|
272
|
+
});
|
|
273
|
+
return timeoutPending2;
|
|
274
|
+
};
|
|
275
|
+
let submitPending2;
|
|
276
|
+
let submitKey2;
|
|
277
|
+
let timeoutPending2;
|
|
226
278
|
return {
|
|
227
279
|
phase: "interaction",
|
|
228
280
|
kind: "extended-text",
|
|
229
281
|
cardinality: "single",
|
|
230
282
|
stimulus,
|
|
231
283
|
interaction,
|
|
232
|
-
submitText
|
|
233
|
-
|
|
234
|
-
return pending2;
|
|
235
|
-
}
|
|
236
|
-
pending2 = ctx.execute({ kind: "interaction", submission: { type: "extended-text", values: [value] } }, "interaction");
|
|
237
|
-
return pending2;
|
|
238
|
-
},
|
|
239
|
-
timeout: function timeout() {
|
|
240
|
-
if (pending2) {
|
|
241
|
-
return pending2;
|
|
242
|
-
}
|
|
243
|
-
pending2 = ctx.execute({ kind: "timeout" }, "timeout");
|
|
244
|
-
return pending2;
|
|
245
|
-
},
|
|
284
|
+
submitText,
|
|
285
|
+
timeout: timeout2,
|
|
246
286
|
toJSON: poisonToJSON
|
|
247
287
|
};
|
|
248
288
|
}
|
|
249
|
-
|
|
289
|
+
const multi = interaction;
|
|
290
|
+
let submitPending;
|
|
291
|
+
let submitKey;
|
|
292
|
+
let timeoutPending;
|
|
293
|
+
function submitTexts(values) {
|
|
294
|
+
const submission = { type: "extended-text", values };
|
|
295
|
+
const key = JSON.stringify(submission);
|
|
296
|
+
if (timeoutPending) {
|
|
297
|
+
return Promise.resolve(ctx.errored(errors4.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
298
|
+
}
|
|
299
|
+
if (submitPending) {
|
|
300
|
+
if (submitKey === key) {
|
|
301
|
+
return submitPending;
|
|
302
|
+
}
|
|
303
|
+
return Promise.resolve(ctx.errored(errors4.wrap(ErrConflict, "cannot submit a different extended-text payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
304
|
+
}
|
|
305
|
+
const validationError = validateExtendedTextSubmission(ctx.log, values, multi.minStrings, multi.maxStrings);
|
|
306
|
+
if (validationError) {
|
|
307
|
+
return Promise.resolve(ctx.errored(validationError, "interaction", { kind: "interaction", submission }));
|
|
308
|
+
}
|
|
309
|
+
submitKey = key;
|
|
310
|
+
submitPending = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
311
|
+
submitPending = undefined;
|
|
312
|
+
submitKey = undefined;
|
|
313
|
+
});
|
|
314
|
+
return submitPending;
|
|
315
|
+
}
|
|
316
|
+
function timeout() {
|
|
317
|
+
const intent = { kind: "timeout" };
|
|
318
|
+
if (submitPending) {
|
|
319
|
+
return Promise.resolve(ctx.errored(errors4.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
320
|
+
}
|
|
321
|
+
if (timeoutPending) {
|
|
322
|
+
return timeoutPending;
|
|
323
|
+
}
|
|
324
|
+
timeoutPending = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
325
|
+
timeoutPending = undefined;
|
|
326
|
+
});
|
|
327
|
+
return timeoutPending;
|
|
328
|
+
}
|
|
250
329
|
return {
|
|
251
330
|
phase: "interaction",
|
|
252
331
|
kind: "extended-text",
|
|
253
332
|
cardinality: "multiple",
|
|
254
333
|
stimulus,
|
|
255
|
-
interaction,
|
|
256
|
-
maxStrings:
|
|
257
|
-
minStrings:
|
|
258
|
-
submitTexts
|
|
259
|
-
|
|
260
|
-
return pending;
|
|
261
|
-
}
|
|
262
|
-
const validationError = validateExtendedTextSubmission(ctx.log, values, interaction.minStrings, interaction.maxStrings);
|
|
263
|
-
if (validationError) {
|
|
264
|
-
return Promise.resolve(ctx.errored(validationError, "interaction", {
|
|
265
|
-
kind: "interaction",
|
|
266
|
-
submission: { type: "extended-text", values }
|
|
267
|
-
}));
|
|
268
|
-
}
|
|
269
|
-
pending = ctx.execute({ kind: "interaction", submission: { type: "extended-text", values } }, "interaction");
|
|
270
|
-
return pending;
|
|
271
|
-
},
|
|
272
|
-
timeout: function timeout() {
|
|
273
|
-
if (pending) {
|
|
274
|
-
return pending;
|
|
275
|
-
}
|
|
276
|
-
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
277
|
-
return pending;
|
|
278
|
-
},
|
|
334
|
+
interaction: multi,
|
|
335
|
+
maxStrings: multi.maxStrings,
|
|
336
|
+
minStrings: multi.minStrings,
|
|
337
|
+
submitTexts,
|
|
338
|
+
timeout,
|
|
279
339
|
toJSON: poisonToJSON
|
|
280
340
|
};
|
|
281
341
|
}
|
|
282
342
|
|
|
283
343
|
// src/feedback-state.ts
|
|
284
|
-
function feedbackState(ctx, stimulus, interaction, submission, isCorrect, feedbackContent,
|
|
344
|
+
function feedbackState(ctx, stimulus, interaction, submission, isCorrect, feedbackContent, review) {
|
|
285
345
|
let pending;
|
|
286
346
|
return {
|
|
287
347
|
phase: "feedback",
|
|
@@ -290,7 +350,7 @@ function feedbackState(ctx, stimulus, interaction, submission, isCorrect, feedba
|
|
|
290
350
|
submission,
|
|
291
351
|
isCorrect,
|
|
292
352
|
feedbackContent,
|
|
293
|
-
|
|
353
|
+
review,
|
|
294
354
|
advance: function advance() {
|
|
295
355
|
if (pending) {
|
|
296
356
|
return pending;
|
|
@@ -391,7 +451,45 @@ function validateMatchSubmission(log, pairs, sourceChoices, targetChoices, minAs
|
|
|
391
451
|
return null;
|
|
392
452
|
}
|
|
393
453
|
function matchState(ctx, stimulus, interaction) {
|
|
394
|
-
let
|
|
454
|
+
let submitPending;
|
|
455
|
+
let submitKey;
|
|
456
|
+
let timeoutPending;
|
|
457
|
+
function submitMatch(pairs) {
|
|
458
|
+
const submission = { type: "match", pairs };
|
|
459
|
+
const key = JSON.stringify(submission);
|
|
460
|
+
if (timeoutPending) {
|
|
461
|
+
return Promise.resolve(ctx.errored(errors5.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
462
|
+
}
|
|
463
|
+
if (submitPending) {
|
|
464
|
+
if (submitKey === key) {
|
|
465
|
+
return submitPending;
|
|
466
|
+
}
|
|
467
|
+
return Promise.resolve(ctx.errored(errors5.wrap(ErrConflict, "cannot submit a different match payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
468
|
+
}
|
|
469
|
+
const validationError = validateMatchSubmission(ctx.log, pairs, interaction.sourceChoices, interaction.targetChoices, interaction.minAssociations, interaction.maxAssociations);
|
|
470
|
+
if (validationError) {
|
|
471
|
+
return Promise.resolve(ctx.errored(validationError, "interaction", { kind: "interaction", submission }));
|
|
472
|
+
}
|
|
473
|
+
submitKey = key;
|
|
474
|
+
submitPending = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
475
|
+
submitPending = undefined;
|
|
476
|
+
submitKey = undefined;
|
|
477
|
+
});
|
|
478
|
+
return submitPending;
|
|
479
|
+
}
|
|
480
|
+
function timeout() {
|
|
481
|
+
const intent = { kind: "timeout" };
|
|
482
|
+
if (submitPending) {
|
|
483
|
+
return Promise.resolve(ctx.errored(errors5.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
484
|
+
}
|
|
485
|
+
if (timeoutPending) {
|
|
486
|
+
return timeoutPending;
|
|
487
|
+
}
|
|
488
|
+
timeoutPending = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
489
|
+
timeoutPending = undefined;
|
|
490
|
+
});
|
|
491
|
+
return timeoutPending;
|
|
492
|
+
}
|
|
395
493
|
return {
|
|
396
494
|
phase: "interaction",
|
|
397
495
|
kind: "match",
|
|
@@ -401,27 +499,8 @@ function matchState(ctx, stimulus, interaction) {
|
|
|
401
499
|
targetChoices: interaction.targetChoices,
|
|
402
500
|
minAssociations: interaction.minAssociations,
|
|
403
501
|
maxAssociations: interaction.maxAssociations,
|
|
404
|
-
submitMatch
|
|
405
|
-
|
|
406
|
-
return pending;
|
|
407
|
-
}
|
|
408
|
-
const validationError = validateMatchSubmission(ctx.log, pairs, interaction.sourceChoices, interaction.targetChoices, interaction.minAssociations, interaction.maxAssociations);
|
|
409
|
-
if (validationError) {
|
|
410
|
-
return Promise.resolve(ctx.errored(validationError, "interaction", {
|
|
411
|
-
kind: "interaction",
|
|
412
|
-
submission: { type: "match", pairs }
|
|
413
|
-
}));
|
|
414
|
-
}
|
|
415
|
-
pending = ctx.execute({ kind: "interaction", submission: { type: "match", pairs } }, "interaction");
|
|
416
|
-
return pending;
|
|
417
|
-
},
|
|
418
|
-
timeout: function timeout() {
|
|
419
|
-
if (pending) {
|
|
420
|
-
return pending;
|
|
421
|
-
}
|
|
422
|
-
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
423
|
-
return pending;
|
|
424
|
-
},
|
|
502
|
+
submitMatch,
|
|
503
|
+
timeout,
|
|
425
504
|
toJSON: poisonToJSON
|
|
426
505
|
};
|
|
427
506
|
}
|
|
@@ -478,7 +557,45 @@ function validateOrderSubmission(log, orderedKeys, choices, minChoices, maxChoic
|
|
|
478
557
|
return null;
|
|
479
558
|
}
|
|
480
559
|
function orderState(ctx, stimulus, interaction) {
|
|
481
|
-
let
|
|
560
|
+
let submitPending;
|
|
561
|
+
let submitKey;
|
|
562
|
+
let timeoutPending;
|
|
563
|
+
function submitOrder(orderedKeys) {
|
|
564
|
+
const submission = { type: "order", orderedKeys };
|
|
565
|
+
const key = JSON.stringify(submission);
|
|
566
|
+
if (timeoutPending) {
|
|
567
|
+
return Promise.resolve(ctx.errored(errors6.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
568
|
+
}
|
|
569
|
+
if (submitPending) {
|
|
570
|
+
if (submitKey === key) {
|
|
571
|
+
return submitPending;
|
|
572
|
+
}
|
|
573
|
+
return Promise.resolve(ctx.errored(errors6.wrap(ErrConflict, "cannot submit a different order payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
574
|
+
}
|
|
575
|
+
const validationError = validateOrderSubmission(ctx.log, orderedKeys, interaction.choices, interaction.minChoices, interaction.maxChoices);
|
|
576
|
+
if (validationError) {
|
|
577
|
+
return Promise.resolve(ctx.errored(validationError, "interaction", { kind: "interaction", submission }));
|
|
578
|
+
}
|
|
579
|
+
submitKey = key;
|
|
580
|
+
submitPending = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
581
|
+
submitPending = undefined;
|
|
582
|
+
submitKey = undefined;
|
|
583
|
+
});
|
|
584
|
+
return submitPending;
|
|
585
|
+
}
|
|
586
|
+
function timeout() {
|
|
587
|
+
const intent = { kind: "timeout" };
|
|
588
|
+
if (submitPending) {
|
|
589
|
+
return Promise.resolve(ctx.errored(errors6.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
590
|
+
}
|
|
591
|
+
if (timeoutPending) {
|
|
592
|
+
return timeoutPending;
|
|
593
|
+
}
|
|
594
|
+
timeoutPending = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
595
|
+
timeoutPending = undefined;
|
|
596
|
+
});
|
|
597
|
+
return timeoutPending;
|
|
598
|
+
}
|
|
482
599
|
return {
|
|
483
600
|
phase: "interaction",
|
|
484
601
|
kind: "order",
|
|
@@ -487,51 +604,52 @@ function orderState(ctx, stimulus, interaction) {
|
|
|
487
604
|
choices: interaction.choices,
|
|
488
605
|
minChoices: interaction.minChoices,
|
|
489
606
|
maxChoices: interaction.maxChoices,
|
|
490
|
-
submitOrder
|
|
491
|
-
|
|
492
|
-
return pending;
|
|
493
|
-
}
|
|
494
|
-
const validationError = validateOrderSubmission(ctx.log, orderedKeys, interaction.choices, interaction.minChoices, interaction.maxChoices);
|
|
495
|
-
if (validationError) {
|
|
496
|
-
return Promise.resolve(ctx.errored(validationError, "interaction", {
|
|
497
|
-
kind: "interaction",
|
|
498
|
-
submission: { type: "order", orderedKeys }
|
|
499
|
-
}));
|
|
500
|
-
}
|
|
501
|
-
pending = ctx.execute({ kind: "interaction", submission: { type: "order", orderedKeys } }, "interaction");
|
|
502
|
-
return pending;
|
|
503
|
-
},
|
|
504
|
-
timeout: function timeout() {
|
|
505
|
-
if (pending) {
|
|
506
|
-
return pending;
|
|
507
|
-
}
|
|
508
|
-
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
509
|
-
return pending;
|
|
510
|
-
},
|
|
607
|
+
submitOrder,
|
|
608
|
+
timeout,
|
|
511
609
|
toJSON: poisonToJSON
|
|
512
610
|
};
|
|
513
611
|
}
|
|
514
612
|
|
|
515
613
|
// src/pci-state.ts
|
|
614
|
+
import * as errors7 from "@superbuilders/errors";
|
|
516
615
|
function pciInteractionState(ctx, stimulus, interaction) {
|
|
517
|
-
let
|
|
616
|
+
let submitPending;
|
|
617
|
+
let submitKey;
|
|
618
|
+
let timeoutPending;
|
|
518
619
|
const { pciId, properties } = interaction;
|
|
519
620
|
function submit(value) {
|
|
520
|
-
|
|
521
|
-
|
|
621
|
+
const submission = { type: "portable-custom", pciId, value };
|
|
622
|
+
const key = JSON.stringify(submission);
|
|
623
|
+
if (timeoutPending) {
|
|
624
|
+
return Promise.resolve(ctx.errored(errors7.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
625
|
+
}
|
|
626
|
+
if (submitPending) {
|
|
627
|
+
if (submitKey === key) {
|
|
628
|
+
return submitPending;
|
|
629
|
+
}
|
|
630
|
+
return Promise.resolve(ctx.errored(errors7.wrap(ErrConflict, "cannot submit a different pci payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
522
631
|
}
|
|
523
632
|
ctx.log?.debug("pci submit", { pciId });
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
633
|
+
submitKey = key;
|
|
634
|
+
submitPending = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
635
|
+
submitPending = undefined;
|
|
636
|
+
submitKey = undefined;
|
|
637
|
+
});
|
|
638
|
+
return submitPending;
|
|
527
639
|
}
|
|
528
640
|
function timeout() {
|
|
529
|
-
|
|
530
|
-
|
|
641
|
+
const intent = { kind: "timeout" };
|
|
642
|
+
if (submitPending) {
|
|
643
|
+
return Promise.resolve(ctx.errored(errors7.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
644
|
+
}
|
|
645
|
+
if (timeoutPending) {
|
|
646
|
+
return timeoutPending;
|
|
531
647
|
}
|
|
532
648
|
ctx.log?.debug("pci timeout", { pciId });
|
|
533
|
-
|
|
534
|
-
|
|
649
|
+
timeoutPending = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
650
|
+
timeoutPending = undefined;
|
|
651
|
+
});
|
|
652
|
+
return timeoutPending;
|
|
535
653
|
}
|
|
536
654
|
return {
|
|
537
655
|
phase: "interaction",
|
|
@@ -547,27 +665,50 @@ function pciInteractionState(ctx, stimulus, interaction) {
|
|
|
547
665
|
}
|
|
548
666
|
|
|
549
667
|
// src/text-entry-state.ts
|
|
668
|
+
import * as errors8 from "@superbuilders/errors";
|
|
550
669
|
function textEntryState(ctx, stimulus, interaction) {
|
|
551
|
-
let
|
|
670
|
+
let submitPending;
|
|
671
|
+
let submitKey;
|
|
672
|
+
let timeoutPending;
|
|
673
|
+
function submitText(value) {
|
|
674
|
+
const submission = { type: "text-entry", value };
|
|
675
|
+
const key = JSON.stringify(submission);
|
|
676
|
+
if (timeoutPending) {
|
|
677
|
+
return Promise.resolve(ctx.errored(errors8.wrap(ErrConflict, "cannot submit while timeout is in flight"), "interaction", { kind: "interaction", submission }));
|
|
678
|
+
}
|
|
679
|
+
if (submitPending) {
|
|
680
|
+
if (submitKey === key) {
|
|
681
|
+
return submitPending;
|
|
682
|
+
}
|
|
683
|
+
return Promise.resolve(ctx.errored(errors8.wrap(ErrConflict, "cannot submit a different text payload while submit is in flight"), "interaction", { kind: "interaction", submission }));
|
|
684
|
+
}
|
|
685
|
+
submitKey = key;
|
|
686
|
+
submitPending = ctx.execute({ kind: "interaction", submission }, "interaction").finally(function clearPending() {
|
|
687
|
+
submitPending = undefined;
|
|
688
|
+
submitKey = undefined;
|
|
689
|
+
});
|
|
690
|
+
return submitPending;
|
|
691
|
+
}
|
|
692
|
+
function timeout() {
|
|
693
|
+
const intent = { kind: "timeout" };
|
|
694
|
+
if (submitPending) {
|
|
695
|
+
return Promise.resolve(ctx.errored(errors8.wrap(ErrConflict, "cannot timeout while submission is in flight"), "timeout", intent));
|
|
696
|
+
}
|
|
697
|
+
if (timeoutPending) {
|
|
698
|
+
return timeoutPending;
|
|
699
|
+
}
|
|
700
|
+
timeoutPending = ctx.execute(intent, "timeout").finally(function clearPending() {
|
|
701
|
+
timeoutPending = undefined;
|
|
702
|
+
});
|
|
703
|
+
return timeoutPending;
|
|
704
|
+
}
|
|
552
705
|
return {
|
|
553
706
|
phase: "interaction",
|
|
554
707
|
kind: "text-entry",
|
|
555
708
|
stimulus,
|
|
556
709
|
interaction,
|
|
557
|
-
submitText
|
|
558
|
-
|
|
559
|
-
return pending;
|
|
560
|
-
}
|
|
561
|
-
pending = ctx.execute({ kind: "interaction", submission: { type: "text-entry", value } }, "interaction");
|
|
562
|
-
return pending;
|
|
563
|
-
},
|
|
564
|
-
timeout: function timeout() {
|
|
565
|
-
if (pending) {
|
|
566
|
-
return pending;
|
|
567
|
-
}
|
|
568
|
-
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
569
|
-
return pending;
|
|
570
|
-
},
|
|
710
|
+
submitText,
|
|
711
|
+
timeout,
|
|
571
712
|
toJSON: poisonToJSON
|
|
572
713
|
};
|
|
573
714
|
}
|
|
@@ -582,12 +723,15 @@ var FATAL_SENTINELS = [
|
|
|
582
723
|
];
|
|
583
724
|
function isFatalError(err) {
|
|
584
725
|
for (const sentinel of FATAL_SENTINELS) {
|
|
585
|
-
if (
|
|
726
|
+
if (errors9.is(err, sentinel)) {
|
|
586
727
|
return true;
|
|
587
728
|
}
|
|
588
729
|
}
|
|
589
730
|
return false;
|
|
590
731
|
}
|
|
732
|
+
function isRetriableError(err) {
|
|
733
|
+
return !errors9.is(err, ErrInvalidSubmission);
|
|
734
|
+
}
|
|
591
735
|
function makeSession(sc) {
|
|
592
736
|
const log = sc.log;
|
|
593
737
|
function resolve(result) {
|
|
@@ -595,18 +739,23 @@ function makeSession(sc) {
|
|
|
595
739
|
case "advanced":
|
|
596
740
|
return fromAdvanced(result.stimulus, result.interaction);
|
|
597
741
|
case "submitted":
|
|
598
|
-
return feedbackState(ctx, result.stimulus, result.interaction, result.submission, result.isCorrect, result.feedbackContent, result.
|
|
742
|
+
return feedbackState(ctx, result.stimulus, result.interaction, result.submission, result.isCorrect, result.feedbackContent, result.review);
|
|
599
743
|
case "completed":
|
|
600
744
|
return { phase: "completed", toJSON: poisonToJSON };
|
|
601
745
|
}
|
|
602
746
|
}
|
|
603
747
|
function errored(error, failedPhase, intent) {
|
|
604
748
|
let pending;
|
|
605
|
-
|
|
749
|
+
const retriable = isRetriableError(error);
|
|
750
|
+
const state = {
|
|
606
751
|
phase: "errored",
|
|
607
752
|
error,
|
|
608
|
-
|
|
753
|
+
retriable,
|
|
609
754
|
retry: function retry() {
|
|
755
|
+
if (!retriable) {
|
|
756
|
+
log?.debug("retry ignored for non-retriable error", { failedPhase });
|
|
757
|
+
return Promise.resolve(state);
|
|
758
|
+
}
|
|
610
759
|
if (pending) {
|
|
611
760
|
return pending;
|
|
612
761
|
}
|
|
@@ -616,6 +765,7 @@ function makeSession(sc) {
|
|
|
616
765
|
},
|
|
617
766
|
toJSON: poisonToJSON
|
|
618
767
|
};
|
|
768
|
+
return state;
|
|
619
769
|
}
|
|
620
770
|
async function execute(intent, phase) {
|
|
621
771
|
const body = {
|
|
@@ -627,7 +777,7 @@ function makeSession(sc) {
|
|
|
627
777
|
if (!result.ok) {
|
|
628
778
|
if (isFatalError(result.error)) {
|
|
629
779
|
log?.error("fatal transport error", { error: result.error, phase });
|
|
630
|
-
return { phase: "fatal", error: result.error, toJSON: poisonToJSON };
|
|
780
|
+
return { phase: "fatal", error: result.error, retriable: false, toJSON: poisonToJSON };
|
|
631
781
|
}
|
|
632
782
|
return errored(result.error, phase, intent);
|
|
633
783
|
}
|
|
@@ -650,7 +800,8 @@ function makeSession(sc) {
|
|
|
650
800
|
log?.error("unsupported pci in frame", { pciId: interaction.pciId });
|
|
651
801
|
return {
|
|
652
802
|
phase: "fatal",
|
|
653
|
-
error:
|
|
803
|
+
error: errors9.wrap(ErrUnsupportedPci, `pci '${interaction.pciId}'`),
|
|
804
|
+
retriable: false,
|
|
654
805
|
toJSON: poisonToJSON
|
|
655
806
|
};
|
|
656
807
|
}
|
|
@@ -683,7 +834,7 @@ function create(config) {
|
|
|
683
834
|
const log = config.logger;
|
|
684
835
|
if (!config.publishableKey.startsWith(PK_PREFIX)) {
|
|
685
836
|
log?.error("malformed publishable key", { prefix: PK_PREFIX });
|
|
686
|
-
throw
|
|
837
|
+
throw errors10.wrap(ErrMalformedPublishableKey, `key must start with '${PK_PREFIX}'`);
|
|
687
838
|
}
|
|
688
839
|
const transport = createTransport({
|
|
689
840
|
publishableKey: config.publishableKey,
|
|
@@ -724,7 +875,10 @@ function inlinesToPlainText(nodes) {
|
|
|
724
875
|
parts.push(node.value);
|
|
725
876
|
break;
|
|
726
877
|
case "italic":
|
|
727
|
-
parts.push(
|
|
878
|
+
parts.push(node.value);
|
|
879
|
+
break;
|
|
880
|
+
case "latex":
|
|
881
|
+
parts.push(node.value);
|
|
728
882
|
break;
|
|
729
883
|
}
|
|
730
884
|
}
|
|
@@ -758,4 +912,4 @@ export {
|
|
|
758
912
|
ADVANCE_PATH
|
|
759
913
|
};
|
|
760
914
|
|
|
761
|
-
//# debugId=
|
|
915
|
+
//# debugId=EEA07DF4CC0D714664756E2164756E21
|