@superbuilders/primer-tives 4.1.0 → 5.0.1

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 CHANGED
@@ -19,7 +19,7 @@ bun add @superbuilders/primer-tives
19
19
 
20
20
  ## Version
21
21
 
22
- The current SDK version is `4.0.5`.
22
+ The current SDK version is `5.0.0`.
23
23
 
24
24
  ## Entrypoints
25
25
 
@@ -384,7 +384,12 @@ async function runPrimer(initialState: PrimerState): Promise<void> {
384
384
  state = await renderAndSubmitInteraction(state)
385
385
  break
386
386
  case "feedback":
387
- renderFeedback(state.feedbackContent, state.assessmentOutcome, state.review)
387
+ if (state.feedbackKind === "submitted") {
388
+ renderSubmittedFeedback(state.feedbackContent, state.assessmentOutcome, state.review)
389
+ }
390
+ if (state.feedbackKind === "timedOut") {
391
+ renderTimeoutFeedback(state.feedbackContent)
392
+ }
388
393
  state = await state.advance()
389
394
  break
390
395
  case "errored":
@@ -588,7 +593,7 @@ Every interaction state includes:
588
593
  | `stimulus` | Optional frame stimulus. |
589
594
  | `interaction` | Full interaction contract object. |
590
595
  | submit method | Kind-specific learner submission operation. |
591
- | `timeout()` | Records that the learner timed out or the host chose to end the attempt without a submission. |
596
+ | `timeout()` | Records that the learner timed out or the host chose to end the attempt without a submission. A successful timeout resolves to timeout feedback before the next frame. |
592
597
 
593
598
  Submission methods validate standard interaction payloads before runtime submission. Invalid standard submissions return `ErroredState` with `ErrInvalidSubmission`.
594
599
 
@@ -807,8 +812,13 @@ type AssessmentOutcome = {
807
812
  value: AssessmentOutcomeValue
808
813
  }
809
814
 
810
- interface FeedbackState<Pcis extends PciId = PciId> {
815
+ type FeedbackState<Pcis extends PciId = PciId> =
816
+ | SubmittedFeedbackState<Pcis>
817
+ | TimedOutFeedbackState<Pcis>
818
+
819
+ interface SubmittedFeedbackState<Pcis extends PciId = PciId> {
811
820
  readonly phase: "feedback"
821
+ readonly feedbackKind: "submitted"
812
822
  readonly body: ContentBlock[]
813
823
  readonly stimulus: RendererStimulus | null
814
824
  readonly interaction: RendererInteraction<Pcis>
@@ -818,9 +828,19 @@ interface FeedbackState<Pcis extends PciId = PciId> {
818
828
  readonly review: InteractionReview<Pcis> | null
819
829
  advance(): Promise<PrimerState<Pcis>>
820
830
  }
831
+
832
+ interface TimedOutFeedbackState<Pcis extends PciId = PciId> {
833
+ readonly phase: "feedback"
834
+ readonly feedbackKind: "timedOut"
835
+ readonly body: ContentBlock[]
836
+ readonly stimulus: RendererStimulus | null
837
+ readonly interaction: RendererInteraction<Pcis>
838
+ readonly feedbackContent: ContentInline[]
839
+ advance(): Promise<PrimerState<Pcis>>
840
+ }
821
841
  ```
822
842
 
823
- Feedback state is returned after a terminal learner submission. Render the submitted frame, submitted value, `assessmentOutcome.value`, feedback content, and optional review data. Call `advance()` when the learner is ready to continue.
843
+ Feedback state is returned after a terminal learner submission or timeout. Switch on `feedbackKind`. Submitted feedback includes the submitted value, `assessmentOutcome.value`, feedback content, and optional review data. Timeout feedback has no submitted value and no correctness outcome. Call `advance()` when the learner is ready to continue.
824
844
 
825
845
  Repeated `advance()` calls while the first one is pending return the same pending result.
826
846
 
@@ -878,6 +898,7 @@ Fatal sentinels:
878
898
  | Sentinel | Meaning |
879
899
  | --- | --- |
880
900
  | `ErrBadRequest` | Primer rejected the runtime request as invalid for the SDK contract. |
901
+ | `ErrCurriculumInstructionalUndeliverable` | The active curriculum instructional has no deliverable frame content. |
881
902
  | `ErrInvalidAccessToken` | The learner token was rejected. |
882
903
  | `ErrTokenExpired` | The learner token expired. |
883
904
  | `ErrForbidden` | The learner is not allowed to continue in this runtime scope. |
@@ -1100,7 +1121,7 @@ if (!validation.ok) {
1100
1121
 
1101
1122
  ## Review Types
1102
1123
 
1103
- `FeedbackState.review` is `InteractionReview | null`.
1124
+ `SubmittedFeedbackState.review` is `InteractionReview | null`. Timeout feedback does not carry review data because no submission was graded.
1104
1125
 
1105
1126
  ```ts
1106
1127
  type InteractionReview<Pcis extends PciId = PciId> =
@@ -1134,7 +1155,7 @@ type ReviewScalarValue =
1134
1155
  | { kind: "pair"; source: string; target: string }
1135
1156
  ```
1136
1157
 
1137
- `review` is for renderer display and inspection. The assessment outcome lives on `FeedbackState.assessmentOutcome.value`.
1158
+ `review` is for renderer display and inspection. The assessment outcome lives on `SubmittedFeedbackState.assessmentOutcome.value`.
1138
1159
 
1139
1160
  ## PCI Registry
1140
1161
 
@@ -1255,6 +1276,7 @@ import {
1255
1276
  ErrAuthUnavailable,
1256
1277
  ErrBadRequest,
1257
1278
  ErrConflict,
1279
+ ErrCurriculumInstructionalUndeliverable,
1258
1280
  ErrForbidden,
1259
1281
  ErrInvalidAccessToken,
1260
1282
  ErrInvalidSubmission,
@@ -1302,6 +1324,7 @@ Runtime errors are represented as `ErroredState` or `FatalState`.
1302
1324
  | `ErrJsonParse` | `ErroredState` | yes | Runtime data could not be interpreted as the SDK contract. |
1303
1325
  | `ErrInvalidSubmission` | `ErroredState` | no | Renderer submitted a value that is invalid for the active interaction. |
1304
1326
  | `ErrBadRequest` | `FatalState` | no | Runtime request violates the SDK contract. |
1327
+ | `ErrCurriculumInstructionalUndeliverable` | `FatalState` | no | Curriculum routing reached an instructional with no deliverable frame content. |
1305
1328
  | `ErrInvalidAccessToken` | `FatalState` | no | Learner token is invalid. |
1306
1329
  | `ErrTokenExpired` | `FatalState` | no | Learner token expired. |
1307
1330
  | `ErrForbidden` | `FatalState` | no | Learner cannot continue in this runtime scope. |
@@ -1369,6 +1392,10 @@ if (state.phase === "fatal") {
1369
1392
  renderSdkUpgradeMessage()
1370
1393
  return
1371
1394
  }
1395
+ if (errors.is(state.error, ErrCurriculumInstructionalUndeliverable)) {
1396
+ renderContentUnavailableMessage()
1397
+ return
1398
+ }
1372
1399
  logger.error({ error: state.error }, "primer fatal state")
1373
1400
  throw state.error
1374
1401
  }
@@ -1442,6 +1469,7 @@ The runtime exchange shape is not public SDK surface. Tests should assert SDK se
1442
1469
  | first runtime work fails recoverably | `start` resolves to `ErroredState` with `retriable: true` |
1443
1470
  | first runtime work fails terminally | `start` resolves to `FatalState` |
1444
1471
  | unsupported PCI is presented | `start` resolves to `FatalState` with `ErrUnsupportedPci` |
1472
+ | curriculum instructional has no deliverable content | transition resolves to `FatalState` with `ErrCurriculumInstructionalUndeliverable` |
1445
1473
  | standard submission is invalid | submit method resolves to `ErroredState` with `ErrInvalidSubmission` |
1446
1474
  | concurrent submit/timeout conflict occurs | transition resolves to `ErroredState` with `ErrConflict` |
1447
1475
  | state is serialized | serialization throws `ErrNotSerializable` |
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-popup.d.ts","sourceRoot":"","sources":["../../../src/client/auth/hosted-popup.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAMtE,KAAK,iBAAiB,GAAG;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B,CAAA;AAgJD,iBAAe,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAU1E;AAED,YAAY,EAAE,iBAAiB,EAAE,CAAA;AACjC,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"hosted-popup.d.ts","sourceRoot":"","sources":["../../../src/client/auth/hosted-popup.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAMtE,KAAK,iBAAiB,GAAG;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B,CAAA;AA0PD,iBAAe,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAU1E;AAED,YAAY,EAAE,iBAAiB,EAAE,CAAA;AACjC,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
@@ -1,10 +1,10 @@
1
1
  import type { SessionContext } from "./session-context";
2
- import type { PrimerState } from "./types";
2
+ import type { InteractionFeedback, PrimerState } from "./types";
3
3
  import type { ContentBlock } from "../contracts/content";
4
4
  import type { PciId } from "../contracts/pci";
5
5
  import type { RendererChoice, RendererInteraction, RendererStimulus } from "../contracts/types";
6
6
  declare function choiceState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: Extract<RendererInteraction<Pcis>, {
7
7
  type: "choice";
8
- }>, options: RendererChoice[], maxChoices: number, minChoices: number): PrimerState<Pcis>;
8
+ }>, options: RendererChoice[], maxChoices: number, minChoices: number, feedback: InteractionFeedback | null): PrimerState<Pcis>;
9
9
  export { choiceState };
10
10
  //# sourceMappingURL=choice-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"choice-state.d.ts","sourceRoot":"","sources":["../../src/client/choice-state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAK3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,MAAM,6CAA6C,CAAA;AAGpD,iBAAS,WAAW,CAAC,IAAI,SAAS,KAAK,EACtC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,EACnE,OAAO,EAAE,cAAc,EAAE,EACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAChB,WAAW,CAAC,IAAI,CAAC,CAsFnB;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"choice-state.d.ts","sourceRoot":"","sources":["../../src/client/choice-state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAKhG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,MAAM,6CAA6C,CAAA;AAGpD,iBAAS,WAAW,CAAC,IAAI,SAAS,KAAK,EACtC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,EACnE,OAAO,EAAE,cAAc,EAAE,EACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAClC,WAAW,CAAC,IAAI,CAAC,CAuFnB;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -1,10 +1,10 @@
1
1
  import type { SessionContext } from "./session-context";
2
- import type { PrimerState } from "./types";
2
+ import type { InteractionFeedback, PrimerState } from "./types";
3
3
  import type { ContentBlock } from "../contracts/content";
4
4
  import type { PciId } from "../contracts/pci";
5
5
  import type { RendererStimulus, StandardRendererInteraction } from "../contracts/types";
6
6
  declare function extendedTextState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: Extract<StandardRendererInteraction, {
7
7
  type: "extended-text";
8
- }>): PrimerState<Pcis>;
8
+ }>, feedback: InteractionFeedback | null): PrimerState<Pcis>;
9
9
  export { extendedTextState };
10
10
  //# sourceMappingURL=extended-text-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extended-text-state.d.ts","sourceRoot":"","sources":["../../src/client/extended-text-state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAK3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,gBAAgB,EAChB,2BAA2B,EAC3B,MAAM,6CAA6C,CAAA;AAGpD,iBAAS,iBAAiB,CAAC,IAAI,SAAS,KAAK,EAC5C,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,OAAO,CAAC,2BAA2B,EAAE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,GAC1E,WAAW,CAAC,IAAI,CAAC,CAuKnB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
1
+ {"version":3,"file":"extended-text-state.d.ts","sourceRoot":"","sources":["../../src/client/extended-text-state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAKhG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,gBAAgB,EAChB,2BAA2B,EAC3B,MAAM,6CAA6C,CAAA;AAGpD,iBAAS,iBAAiB,CAAC,IAAI,SAAS,KAAK,EAC5C,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,OAAO,CAAC,2BAA2B,EAAE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,EAC5E,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAClC,WAAW,CAAC,IAAI,CAAC,CAyKnB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
@@ -4,6 +4,7 @@ import type { ContentBlock, ContentInline } from "../contracts/content";
4
4
  import type { PciId } from "../contracts/pci";
5
5
  import type { InteractionReview } from "../contracts/review";
6
6
  import type { RendererInteraction, RendererStimulus, RendererSubmission } from "../contracts/types";
7
- declare function feedbackState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: RendererInteraction<Pcis>, submission: RendererSubmission<Pcis>, assessmentOutcome: AssessmentOutcome, feedbackContent: ContentInline[], review: InteractionReview<Pcis> | null): PrimerState<Pcis>;
8
- export { feedbackState };
7
+ declare function submittedFeedbackState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: RendererInteraction<Pcis>, submission: RendererSubmission<Pcis>, assessmentOutcome: AssessmentOutcome, feedbackContent: ContentInline[], review: InteractionReview<Pcis> | null): PrimerState<Pcis>;
8
+ declare function timedOutFeedbackState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: RendererInteraction<Pcis>, feedbackContent: ContentInline[]): PrimerState<Pcis>;
9
+ export { submittedFeedbackState, timedOutFeedbackState };
9
10
  //# sourceMappingURL=feedback-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-state.d.ts","sourceRoot":"","sources":["../../src/client/feedback-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAC9F,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+CAA+C,CAAA;AAChG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAA;AACrF,OAAO,KAAK,EACX,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,6CAA6C,CAAA;AAEpD,iBAAS,aAAa,CAAC,IAAI,SAAS,KAAK,EACxC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,mBAAmB,CAAC,IAAI,CAAC,EACtC,UAAU,EAAE,kBAAkB,CAAC,IAAI,CAAC,EACpC,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,aAAa,EAAE,EAChC,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,GAAG,IAAI,GACpC,WAAW,CAAC,IAAI,CAAC,CAoBnB;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
1
+ {"version":3,"file":"feedback-state.d.ts","sourceRoot":"","sources":["../../src/client/feedback-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAC9F,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+CAA+C,CAAA;AAChG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAA;AACrF,OAAO,KAAK,EACX,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,6CAA6C,CAAA;AAapD,iBAAS,sBAAsB,CAAC,IAAI,SAAS,KAAK,EACjD,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,mBAAmB,CAAC,IAAI,CAAC,EACtC,UAAU,EAAE,kBAAkB,CAAC,IAAI,CAAC,EACpC,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,aAAa,EAAE,EAChC,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,GAAG,IAAI,GACpC,WAAW,CAAC,IAAI,CAAC,CAcnB;AAED,iBAAS,qBAAqB,CAAC,IAAI,SAAS,KAAK,EAChD,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,IAAI,EAAE,YAAY,EAAE,EACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,EAAE,mBAAmB,CAAC,IAAI,CAAC,EACtC,eAAe,EAAE,aAAa,EAAE,GAC9B,WAAW,CAAC,IAAI,CAAC,CAWnB;AAED,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
1
  export type { PrimerOptions, PrimerOptionsWithAccessToken, PrimerOptionsWithManagedAuth } from "./start";
2
2
  export { start } from "./start";
3
- export type { AccessTokenStartState, AssessmentOutcome, AssessmentOutcomeValue, AuthConfigInvalidState, AuthUnavailableState, ChoiceState, CompletedState, ErroredState, ExtendedTextMultipleState, ExtendedTextSingleState, ExtendedTextState, FatalState, FeedbackState, InteractionState, ManagedStartState, MatchState, NonRetriableErroredState, NonSerializable, ObservationState, OrderState, PciInteractionState, PciPendingRenderProps, PciRenderProps, PciSubmittedRenderProps, PrimerState, RetriableErroredState, RuntimeState, SignInFailedState, SignInRequiredState, TextEntryState } from "./types";
3
+ export type { AccessTokenStartState, AssessmentOutcome, AssessmentOutcomeValue, AuthConfigInvalidState, AuthUnavailableState, ChoiceState, CompletedState, ErroredState, ExtendedTextMultipleState, ExtendedTextSingleState, ExtendedTextState, FatalState, FeedbackKind, FeedbackState, InteractionFeedback, InteractionState, ManagedStartState, MatchState, NonRetriableErroredState, NonSerializable, ObservationState, OrderState, PciInteractionState, PciPendingRenderProps, PciRenderProps, PciSubmittedRenderProps, PrimerState, RetriableErroredState, RuntimeState, SignInFailedState, SignInRequiredState, SubmittedFeedbackState, TextEntryState, TimedOutFeedbackState } from "./types";
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,aAAa,EACb,4BAA4B,EAC5B,4BAA4B,EAC5B,MAAM,0CAA0C,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAA;AAEhE,YAAY,EACX,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,EACvB,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,MAAM,0CAA0C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,aAAa,EACb,4BAA4B,EAC5B,4BAA4B,EAC5B,MAAM,0CAA0C,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAA;AAEhE,YAAY,EACX,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,uBAAuB,EACvB,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,MAAM,0CAA0C,CAAA"}
@@ -6279,6 +6279,7 @@ var ErrAuthStateMismatch = errors.new("auth state mismatch");
6279
6279
  var ErrAuthPopupBlocked = errors.new("auth popup blocked");
6280
6280
  var ErrAuthCancelled = errors.new("auth cancelled");
6281
6281
  var ErrSdkUpgradeRequired = errors.new("sdk upgrade required");
6282
+ var ErrCurriculumInstructionalUndeliverable = errors.new("curriculum instructional undeliverable");
6282
6283
  // src/contracts/content.ts
6283
6284
  function inlinesToPlainText(nodes) {
6284
6285
  const parts = [];
@@ -6956,7 +6957,10 @@ function readPopupMessage(event, popup, config, expectedOrigin) {
6956
6957
  }
6957
6958
  return { kind: "success", accessToken };
6958
6959
  }
6959
- async function waitForPopupMessage(popup, config, expectedOrigin) {
6960
+ function supportsAsyncDisposableStack() {
6961
+ return typeof Reflect.get(globalThis, "AsyncDisposableStack") === "function";
6962
+ }
6963
+ async function waitForPopupMessageWithAsyncDisposableStack(popup, config, expectedOrigin) {
6960
6964
  let __stack = [];
6961
6965
  try {
6962
6966
  const logger = config.logger;
@@ -7023,6 +7027,86 @@ async function waitForPopupMessage(popup, config, expectedOrigin) {
7023
7027
  _promise && await _promise;
7024
7028
  }
7025
7029
  }
7030
+ function cleanupManualPopupWait(cleanups) {
7031
+ for (let index = cleanups.length - 1;index >= 0; index -= 1) {
7032
+ const cleanup = cleanups[index];
7033
+ if (cleanup === undefined) {
7034
+ continue;
7035
+ }
7036
+ cleanup();
7037
+ }
7038
+ }
7039
+ async function waitForPopupMessageWithManualCleanup(popup, config, expectedOrigin) {
7040
+ const logger = config.logger;
7041
+ const cleanups = [];
7042
+ cleanups.push(function closePopup() {
7043
+ popup.close();
7044
+ });
7045
+ const pending = new Promise(function waitForMessage(resolve, reject) {
7046
+ let settled = false;
7047
+ function finishWithError(error) {
7048
+ if (settled) {
7049
+ return;
7050
+ }
7051
+ settled = true;
7052
+ reject(error);
7053
+ }
7054
+ function finishWithToken(token) {
7055
+ if (settled) {
7056
+ return;
7057
+ }
7058
+ settled = true;
7059
+ logger.debug("hosted auth popup completed");
7060
+ resolve(token);
7061
+ }
7062
+ const timeoutId = globalThis.setTimeout(function timeout() {
7063
+ logger.error("hosted auth popup timed out");
7064
+ finishWithError(ErrAuthCancelled);
7065
+ }, DEFAULT_POPUP_TIMEOUT_MS);
7066
+ cleanups.push(function clearPopupTimeout() {
7067
+ globalThis.clearTimeout(timeoutId);
7068
+ });
7069
+ const closedPollId = globalThis.setInterval(function checkClosed() {
7070
+ if (!popup.closed) {
7071
+ return;
7072
+ }
7073
+ logger.error("hosted auth popup closed");
7074
+ finishWithError(ErrAuthCancelled);
7075
+ }, POPUP_POLL_MS);
7076
+ cleanups.push(function clearClosedPoll() {
7077
+ globalThis.clearInterval(closedPollId);
7078
+ });
7079
+ function handleMessage(event) {
7080
+ const result = readPopupMessage(event, popup, config, expectedOrigin);
7081
+ if (result.kind === "ignore") {
7082
+ return;
7083
+ }
7084
+ if (result.kind === "error") {
7085
+ logger.error({ error: result.error }, "hosted auth popup failed");
7086
+ finishWithError(result.error);
7087
+ return;
7088
+ }
7089
+ finishWithToken(result.accessToken);
7090
+ }
7091
+ globalThis.addEventListener("message", handleMessage);
7092
+ cleanups.push(function removeMessageListener() {
7093
+ globalThis.removeEventListener("message", handleMessage);
7094
+ });
7095
+ });
7096
+ return pending.then(function cleanupSuccess(token) {
7097
+ cleanupManualPopupWait(cleanups);
7098
+ return token;
7099
+ }, function cleanupFailure(error) {
7100
+ cleanupManualPopupWait(cleanups);
7101
+ throw error;
7102
+ });
7103
+ }
7104
+ async function waitForPopupMessage(popup, config, expectedOrigin) {
7105
+ if (supportsAsyncDisposableStack()) {
7106
+ return waitForPopupMessageWithAsyncDisposableStack(popup, config, expectedOrigin);
7107
+ }
7108
+ return waitForPopupMessageWithManualCleanup(popup, config, expectedOrigin);
7109
+ }
7026
7110
  async function beginHostedPopup(config) {
7027
7111
  const logger = config.logger;
7028
7112
  const url = hostedAuthUrl(config);
@@ -7207,7 +7291,7 @@ import * as errors11 from "@superbuilders/errors";
7207
7291
 
7208
7292
  // src/client/choice-state.ts
7209
7293
  import * as errors5 from "@superbuilders/errors";
7210
- function choiceState(ctx, body, stimulus, interaction, options, maxChoices, minChoices) {
7294
+ function choiceState(ctx, body, stimulus, interaction, options, maxChoices, minChoices, feedback) {
7211
7295
  let submitPending;
7212
7296
  let submitKey;
7213
7297
  let timeoutPending;
@@ -7254,6 +7338,7 @@ function choiceState(ctx, body, stimulus, interaction, options, maxChoices, minC
7254
7338
  body,
7255
7339
  stimulus,
7256
7340
  interaction,
7341
+ feedback,
7257
7342
  options,
7258
7343
  maxChoices,
7259
7344
  minChoices,
@@ -7265,7 +7350,7 @@ function choiceState(ctx, body, stimulus, interaction, options, maxChoices, minC
7265
7350
 
7266
7351
  // src/client/extended-text-state.ts
7267
7352
  import * as errors6 from "@superbuilders/errors";
7268
- function extendedTextState(ctx, body, stimulus, interaction) {
7353
+ function extendedTextState(ctx, body, stimulus, interaction, feedback) {
7269
7354
  if (interaction.cardinality === "single") {
7270
7355
  let submitText = function(value) {
7271
7356
  const submission = { type: "extended-text", values: [value] };
@@ -7313,6 +7398,7 @@ function extendedTextState(ctx, body, stimulus, interaction) {
7313
7398
  body,
7314
7399
  stimulus,
7315
7400
  interaction,
7401
+ feedback,
7316
7402
  submitText,
7317
7403
  timeout: timeout2,
7318
7404
  toJSON: poisonToJSON
@@ -7366,6 +7452,7 @@ function extendedTextState(ctx, body, stimulus, interaction) {
7366
7452
  body,
7367
7453
  stimulus,
7368
7454
  interaction: multi,
7455
+ feedback,
7369
7456
  maxStrings: multi.maxStrings,
7370
7457
  minStrings: multi.minStrings,
7371
7458
  submitTexts,
@@ -7375,10 +7462,20 @@ function extendedTextState(ctx, body, stimulus, interaction) {
7375
7462
  }
7376
7463
 
7377
7464
  // src/client/feedback-state.ts
7378
- function feedbackState(ctx, body, stimulus, interaction, submission, assessmentOutcome, feedbackContent, review) {
7465
+ function createAdvance(ctx) {
7379
7466
  let pending;
7467
+ return function advance() {
7468
+ if (pending) {
7469
+ return pending;
7470
+ }
7471
+ pending = ctx.execute({ kind: "observation" }, "observation");
7472
+ return pending;
7473
+ };
7474
+ }
7475
+ function submittedFeedbackState(ctx, body, stimulus, interaction, submission, assessmentOutcome, feedbackContent, review) {
7380
7476
  return {
7381
7477
  phase: "feedback",
7478
+ feedbackKind: "submitted",
7382
7479
  body,
7383
7480
  stimulus,
7384
7481
  interaction,
@@ -7386,20 +7483,26 @@ function feedbackState(ctx, body, stimulus, interaction, submission, assessmentO
7386
7483
  assessmentOutcome,
7387
7484
  feedbackContent,
7388
7485
  review,
7389
- advance: function advance() {
7390
- if (pending) {
7391
- return pending;
7392
- }
7393
- pending = ctx.execute({ kind: "observation" }, "observation");
7394
- return pending;
7395
- },
7486
+ advance: createAdvance(ctx),
7487
+ toJSON: poisonToJSON
7488
+ };
7489
+ }
7490
+ function timedOutFeedbackState(ctx, body, stimulus, interaction, feedbackContent) {
7491
+ return {
7492
+ phase: "feedback",
7493
+ feedbackKind: "timedOut",
7494
+ body,
7495
+ stimulus,
7496
+ interaction,
7497
+ feedbackContent,
7498
+ advance: createAdvance(ctx),
7396
7499
  toJSON: poisonToJSON
7397
7500
  };
7398
7501
  }
7399
7502
 
7400
7503
  // src/client/match-state.ts
7401
7504
  import * as errors7 from "@superbuilders/errors";
7402
- function matchState(ctx, body, stimulus, interaction) {
7505
+ function matchState(ctx, body, stimulus, interaction, feedback) {
7403
7506
  let submitPending;
7404
7507
  let submitKey;
7405
7508
  let timeoutPending;
@@ -7446,6 +7549,7 @@ function matchState(ctx, body, stimulus, interaction) {
7446
7549
  body,
7447
7550
  stimulus,
7448
7551
  interaction,
7552
+ feedback,
7449
7553
  sourceChoices: interaction.sourceChoices,
7450
7554
  targetChoices: interaction.targetChoices,
7451
7555
  minAssociations: interaction.minAssociations,
@@ -7476,7 +7580,7 @@ function observationState(ctx, body, stimulus) {
7476
7580
 
7477
7581
  // src/client/order-state.ts
7478
7582
  import * as errors8 from "@superbuilders/errors";
7479
- function orderState(ctx, body, stimulus, interaction) {
7583
+ function orderState(ctx, body, stimulus, interaction, feedback) {
7480
7584
  let submitPending;
7481
7585
  let submitKey;
7482
7586
  let timeoutPending;
@@ -7523,6 +7627,7 @@ function orderState(ctx, body, stimulus, interaction) {
7523
7627
  body,
7524
7628
  stimulus,
7525
7629
  interaction,
7630
+ feedback,
7526
7631
  choices: interaction.choices,
7527
7632
  minChoices: interaction.minChoices,
7528
7633
  maxChoices: interaction.maxChoices,
@@ -7534,7 +7639,7 @@ function orderState(ctx, body, stimulus, interaction) {
7534
7639
 
7535
7640
  // src/client/pci-state.ts
7536
7641
  import * as errors9 from "@superbuilders/errors";
7537
- function pciInteractionState(ctx, body, stimulus, interaction) {
7642
+ function pciInteractionState(ctx, body, stimulus, interaction, feedback) {
7538
7643
  let submitPending;
7539
7644
  let submitKey;
7540
7645
  let timeoutPending;
@@ -7579,6 +7684,7 @@ function pciInteractionState(ctx, body, stimulus, interaction) {
7579
7684
  body,
7580
7685
  stimulus,
7581
7686
  interaction,
7687
+ feedback,
7582
7688
  pciId,
7583
7689
  properties,
7584
7690
  submit,
@@ -7589,7 +7695,7 @@ function pciInteractionState(ctx, body, stimulus, interaction) {
7589
7695
 
7590
7696
  // src/client/text-entry-state.ts
7591
7697
  import * as errors10 from "@superbuilders/errors";
7592
- function textEntryState(ctx, body, stimulus, interaction) {
7698
+ function textEntryState(ctx, body, stimulus, interaction, feedback) {
7593
7699
  let submitPending;
7594
7700
  let submitKey;
7595
7701
  let timeoutPending;
@@ -7636,6 +7742,7 @@ function textEntryState(ctx, body, stimulus, interaction) {
7636
7742
  body,
7637
7743
  stimulus,
7638
7744
  interaction,
7745
+ feedback,
7639
7746
  submitText,
7640
7747
  timeout,
7641
7748
  toJSON: poisonToJSON
@@ -7645,6 +7752,7 @@ function textEntryState(ctx, body, stimulus, interaction) {
7645
7752
  // src/client/session.ts
7646
7753
  var FATAL_SENTINELS = [
7647
7754
  ErrBadRequest,
7755
+ ErrCurriculumInstructionalUndeliverable,
7648
7756
  ErrInvalidAccessToken,
7649
7757
  ErrTokenExpired,
7650
7758
  ErrForbidden,
@@ -7668,7 +7776,7 @@ function makeSession(sc) {
7668
7776
  function resolve(result) {
7669
7777
  switch (result.outcome) {
7670
7778
  case "advanced":
7671
- return fromAdvanced(result.frame.body, result.frame.stimulus, result.frame.interaction);
7779
+ return fromAdvanced(result.frame.body, result.frame.stimulus, result.frame.interaction, result.frame.feedback);
7672
7780
  case "submitted": {
7673
7781
  const interaction = result.frame.interaction;
7674
7782
  if (interaction === null) {
@@ -7681,9 +7789,26 @@ function makeSession(sc) {
7681
7789
  };
7682
7790
  }
7683
7791
  if (result.assessmentOutcome.value === "revisionRequested") {
7684
- return fromAdvanced(result.frame.body, result.frame.stimulus, interaction);
7792
+ const feedback = {
7793
+ assessmentOutcome: result.assessmentOutcome,
7794
+ feedbackContent: result.feedbackContent
7795
+ };
7796
+ return fromAdvanced(result.frame.body, result.frame.stimulus, interaction, feedback);
7797
+ }
7798
+ return submittedFeedbackState(ctx, result.frame.body, result.frame.stimulus, interaction, result.submission, result.assessmentOutcome, result.feedbackContent, result.review);
7799
+ }
7800
+ case "timedOut": {
7801
+ const interaction = result.frame.interaction;
7802
+ if (interaction === null) {
7803
+ logger.error("timed out result without interaction");
7804
+ return {
7805
+ phase: "fatal",
7806
+ error: errors11.wrap(ErrBadRequest, "timed out result missing interaction"),
7807
+ retriable: false,
7808
+ toJSON: poisonToJSON
7809
+ };
7685
7810
  }
7686
- return feedbackState(ctx, result.frame.body, result.frame.stimulus, interaction, result.submission, result.assessmentOutcome, result.feedbackContent, result.review);
7811
+ return timedOutFeedbackState(ctx, result.frame.body, result.frame.stimulus, interaction, result.feedbackContent);
7687
7812
  }
7688
7813
  case "completed":
7689
7814
  return { phase: "completed", toJSON: poisonToJSON };
@@ -7769,7 +7894,7 @@ function makeSession(sc) {
7769
7894
  }
7770
7895
  return false;
7771
7896
  }
7772
- function fromAdvanced(body, stimulus, interaction) {
7897
+ function fromAdvanced(body, stimulus, interaction, feedback) {
7773
7898
  if (interaction === null) {
7774
7899
  return observationState(ctx, body, stimulus);
7775
7900
  }
@@ -7784,9 +7909,9 @@ function makeSession(sc) {
7784
7909
  };
7785
7910
  }
7786
7911
  }
7787
- return pendingInteractionState(body, stimulus, interaction);
7912
+ return pendingInteractionState(body, stimulus, interaction, feedback);
7788
7913
  }
7789
- function extendedTextInteractionState(body, stimulus, interaction) {
7914
+ function extendedTextInteractionState(body, stimulus, interaction, feedback) {
7790
7915
  if (!("cardinality" in interaction)) {
7791
7916
  logger.error("extended-text interaction is unsupported");
7792
7917
  return {
@@ -7797,22 +7922,22 @@ function makeSession(sc) {
7797
7922
  };
7798
7923
  }
7799
7924
  const extendedInteraction = interaction;
7800
- return extendedTextState(ctx, body, stimulus, extendedInteraction);
7925
+ return extendedTextState(ctx, body, stimulus, extendedInteraction, feedback);
7801
7926
  }
7802
- function pendingInteractionState(body, stimulus, interaction) {
7927
+ function pendingInteractionState(body, stimulus, interaction, feedback) {
7803
7928
  switch (interaction.type) {
7804
7929
  case "choice":
7805
- return choiceState(ctx, body, stimulus, interaction, interaction.options, interaction.maxChoices, interaction.minChoices);
7930
+ return choiceState(ctx, body, stimulus, interaction, interaction.options, interaction.maxChoices, interaction.minChoices, feedback);
7806
7931
  case "text-entry":
7807
- return textEntryState(ctx, body, stimulus, interaction);
7932
+ return textEntryState(ctx, body, stimulus, interaction, feedback);
7808
7933
  case "extended-text":
7809
- return extendedTextInteractionState(body, stimulus, interaction);
7934
+ return extendedTextInteractionState(body, stimulus, interaction, feedback);
7810
7935
  case "order":
7811
- return orderState(ctx, body, stimulus, interaction);
7936
+ return orderState(ctx, body, stimulus, interaction, feedback);
7812
7937
  case "match":
7813
- return matchState(ctx, body, stimulus, interaction);
7938
+ return matchState(ctx, body, stimulus, interaction, feedback);
7814
7939
  case "portable-custom":
7815
- return pciInteractionState(ctx, body, stimulus, interaction);
7940
+ return pciInteractionState(ctx, body, stimulus, interaction, feedback);
7816
7941
  }
7817
7942
  }
7818
7943
  const ctx = { logger, execute, errored };
@@ -7823,7 +7948,7 @@ function makeSession(sc) {
7823
7948
  import * as errors12 from "@superbuilders/errors";
7824
7949
 
7825
7950
  // src/version.ts
7826
- var SDK_VERSION = "4.1.0";
7951
+ var SDK_VERSION = "5.0.0";
7827
7952
  var NPM_PACKAGE_URL = "https://www.npmjs.com/package/@superbuilders/primer-tives";
7828
7953
 
7829
7954
  // src/client/transport.ts
@@ -7881,6 +8006,9 @@ function httpSentinel(status, body) {
7881
8006
  if (parsed?.error === "sdk_upgrade_required") {
7882
8007
  return ErrSdkUpgradeRequired;
7883
8008
  }
8009
+ if (parsed?.error === "curriculum_instructional_undeliverable") {
8010
+ return ErrCurriculumInstructionalUndeliverable;
8011
+ }
7884
8012
  return ErrBadRequest;
7885
8013
  }
7886
8014
  if (status === 401) {
@@ -8039,6 +8167,12 @@ function primerOrigin(origin) {
8039
8167
  }
8040
8168
  return DEFAULT_PRIMER_ORIGIN;
8041
8169
  }
8170
+ function primerAuthOrigin(authOrigin, origin) {
8171
+ if (authOrigin !== undefined) {
8172
+ return authOrigin;
8173
+ }
8174
+ return origin;
8175
+ }
8042
8176
  async function startRuntime(config, resolved) {
8043
8177
  let reauthenticate = null;
8044
8178
  if (resolved.clearCachedAccessToken !== undefined) {
@@ -8082,7 +8216,7 @@ function makeSignInFailedState(config, error) {
8082
8216
  }
8083
8217
  async function loginAndStart(config) {
8084
8218
  const result = await beginHostedLogin({
8085
- origin: config.origin,
8219
+ origin: config.authOrigin,
8086
8220
  publishableKey: config.publishableKey,
8087
8221
  logger: config.logger
8088
8222
  });
@@ -8107,6 +8241,7 @@ async function start(options) {
8107
8241
  const config = {
8108
8242
  publishableKey: options.publishableKey,
8109
8243
  origin,
8244
+ authOrigin: primerAuthOrigin(options.authOrigin, origin),
8110
8245
  fetch: options.fetch,
8111
8246
  abort: options.abort,
8112
8247
  logger,
@@ -8139,4 +8274,4 @@ export {
8139
8274
  start
8140
8275
  };
8141
8276
 
8142
- //# debugId=8BB175F09E303E4A64756E2164756E21
8277
+ //# debugId=5F7821132D289BDA64756E2164756E21