@superbuilders/primer-tives 1.1.4 → 2.0.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 +20 -11
- package/dist/client/choice-state.d.ts +2 -1
- package/dist/client/choice-state.d.ts.map +1 -1
- package/dist/client/create.d.ts +1 -1
- package/dist/client/create.d.ts.map +1 -1
- package/dist/client/extended-text-state.d.ts +2 -1
- package/dist/client/extended-text-state.d.ts.map +1 -1
- package/dist/client/feedback-state.d.ts +2 -2
- package/dist/client/feedback-state.d.ts.map +1 -1
- package/dist/client/index.js +145 -61
- package/dist/client/index.js.map +16 -15
- package/dist/client/match-state.d.ts +2 -1
- package/dist/client/match-state.d.ts.map +1 -1
- package/dist/client/observation-state.d.ts +2 -1
- package/dist/client/observation-state.d.ts.map +1 -1
- package/dist/client/order-state.d.ts +2 -1
- package/dist/client/order-state.d.ts.map +1 -1
- package/dist/client/pci-state.d.ts +2 -1
- package/dist/client/pci-state.d.ts.map +1 -1
- package/dist/client/session-context.d.ts +1 -1
- package/dist/client/session-context.d.ts.map +1 -1
- package/dist/client/session.d.ts +1 -1
- package/dist/client/session.d.ts.map +1 -1
- package/dist/client/text-entry-state.d.ts +2 -1
- package/dist/client/text-entry-state.d.ts.map +1 -1
- package/dist/client/transport.d.ts +9 -6
- package/dist/client/transport.d.ts.map +1 -1
- package/dist/client/types.d.ts +10 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/types.d.ts +5 -9
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +5 -1
- package/dist/errors.js.map +3 -3
- package/dist/server/create-server.d.ts +6 -4
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/index.js +3 -1
- package/dist/server/index.js.map +4 -4
- package/dist/version.d.ts +4 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,20 +10,18 @@ bun add @superbuilders/primer-tives
|
|
|
10
10
|
|
|
11
11
|
## Subpaths
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Every symbol is exported from exactly one subpath. Import from the subpath that owns the thing you need.
|
|
14
14
|
|
|
15
15
|
| Subpath | What it owns |
|
|
16
16
|
|---|---|
|
|
17
17
|
| `@superbuilders/primer-tives/server` | `createPrimerServer` and the four `PrimerServer` methods, the config and return types |
|
|
18
18
|
| `@superbuilders/primer-tives/client` | `create` (browser SDK), the `PrimerState` discriminated union, every `*State` interface, the PCI render props |
|
|
19
19
|
| `@superbuilders/primer-tives/contracts` | wire-shape types (`RendererInteraction`, `RendererSubmission`, `ContentInline`, PCI base types, review types), Zod schemas, the optional submission validator |
|
|
20
|
-
| `@superbuilders/primer-tives/errors` | every error sentinel (`Err…`)
|
|
20
|
+
| `@superbuilders/primer-tives/errors` | every error sentinel (`Err…`) |
|
|
21
21
|
| `@superbuilders/primer-tives/logger` | the `PrimerLogger` interface, accepted by both server and client config |
|
|
22
22
|
| `@superbuilders/primer-tives/grade-level` | `GradeLevel` type and the `GRADE_LEVELS` constant |
|
|
23
23
|
| `@superbuilders/primer-tives/subject` | `Subject`, `SubjectScope`, the `SUBJECTS` constant |
|
|
24
24
|
|
|
25
|
-
There is **no convenience re-export**. Importing `ErrInvalidSecretKey` from `/server` or `/client` will not work — it lives at `/errors` only. Same for `PrimerLogger` (`/logger`), grade level constants (`/grade-level`), subjects (`/subject`), and every wire-shape type (`/contracts`).
|
|
26
|
-
|
|
27
25
|
## End-to-end examples
|
|
28
26
|
|
|
29
27
|
### Native/manual student flow
|
|
@@ -157,6 +155,7 @@ const { studentId, accessToken, expiresInSeconds } = sessionResult.data
|
|
|
157
155
|
```ts
|
|
158
156
|
import { create } from "@superbuilders/primer-tives/client"
|
|
159
157
|
import type { PrimerState } from "@superbuilders/primer-tives/client"
|
|
158
|
+
import * as logger from "@superbuilders/slog"
|
|
160
159
|
|
|
161
160
|
const client = create({
|
|
162
161
|
accessToken,
|
|
@@ -165,7 +164,8 @@ const client = create({
|
|
|
165
164
|
supportedPcis: [
|
|
166
165
|
"urn:primer:pci:division-remainder",
|
|
167
166
|
"urn:primer:pci:fraction-addition"
|
|
168
|
-
]
|
|
167
|
+
],
|
|
168
|
+
logger
|
|
169
169
|
})
|
|
170
170
|
|
|
171
171
|
let state: PrimerState = await client.start()
|
|
@@ -173,7 +173,7 @@ let state: PrimerState = await client.start()
|
|
|
173
173
|
while (state.phase !== "completed" && state.phase !== "fatal") {
|
|
174
174
|
switch (state.phase) {
|
|
175
175
|
case "observation":
|
|
176
|
-
|
|
176
|
+
renderFrame(state.body, state.stimulus)
|
|
177
177
|
state = await state.advance()
|
|
178
178
|
break
|
|
179
179
|
case "interaction":
|
|
@@ -252,7 +252,7 @@ Partial upsert of a native/manual student's placement-routing hints. Omitted fie
|
|
|
252
252
|
const { gradeLevel } = await primer.setStudentHints(studentId, { gradeLevel: "3" })
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
- Required for native/manual students before their first session
|
|
255
|
+
- Required for native/manual students before their first session. If the browser calls `/advance` without a `gradeLevel` on record, the server returns HTTP 412 `needs_hints` and the SDK surfaces it as `ErrNeedsHints` on a `fatal` state.
|
|
256
256
|
- Safe to call repeatedly. Each call is a partial upsert.
|
|
257
257
|
- Not needed for Timeback-linked students: `exchangeTimebackStudentForAccessToken` syncs the grade level from the authority on every call.
|
|
258
258
|
- Throws `ErrStudentNotFound` if `studentId` is unknown; `ErrBadRequest` if the payload fails validation (e.g. unsupported `gradeLevel`).
|
|
@@ -347,7 +347,7 @@ interface Config<Pcis extends PciId = PciId> {
|
|
|
347
347
|
readonly subject: SubjectScope
|
|
348
348
|
readonly fetch?: typeof globalThis.fetch
|
|
349
349
|
readonly abort?: AbortController
|
|
350
|
-
readonly logger
|
|
350
|
+
readonly logger: PrimerLogger
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
interface Client<Pcis extends PciId = PciId> {
|
|
@@ -392,6 +392,7 @@ Every `InteractionState` shape also exposes `timeout(): Promise<PrimerState>`.
|
|
|
392
392
|
```ts
|
|
393
393
|
interface FeedbackState extends NonSerializable {
|
|
394
394
|
readonly phase: "feedback"
|
|
395
|
+
readonly body: ContentBlock[]
|
|
395
396
|
readonly stimulus: RendererStimulus | null
|
|
396
397
|
readonly interaction: RendererInteraction
|
|
397
398
|
readonly submission: RendererSubmission
|
|
@@ -402,7 +403,13 @@ interface FeedbackState extends NonSerializable {
|
|
|
402
403
|
}
|
|
403
404
|
```
|
|
404
405
|
|
|
405
|
-
|
|
406
|
+
Every state that carries frame content (`ObservationState`, every `InteractionState` variant, `FeedbackState`) exposes the frame as three independent fields:
|
|
407
|
+
|
|
408
|
+
- `body: ContentBlock[]` — the frame's prose, possibly empty.
|
|
409
|
+
- `stimulus: RendererStimulus | null` — a discriminated union over media kinds (currently `{ kind: "image", alt, src }`).
|
|
410
|
+
- `interaction: RendererInteraction | null` — the question, when present.
|
|
411
|
+
|
|
412
|
+
`RendererStimulus`, `RendererInteraction`, `RendererSubmission`, `ContentBlock`, `ContentInline`, `InteractionReview` all come from `/contracts`.
|
|
406
413
|
|
|
407
414
|
### `ErroredState`
|
|
408
415
|
|
|
@@ -489,7 +496,6 @@ import type {
|
|
|
489
496
|
PciSubmission,
|
|
490
497
|
// stimulus shapes
|
|
491
498
|
RendererStimulus,
|
|
492
|
-
BodyStimulus,
|
|
493
499
|
ImageStimulus,
|
|
494
500
|
// choice shapes
|
|
495
501
|
RendererChoice,
|
|
@@ -609,6 +615,7 @@ import {
|
|
|
609
615
|
ErrTokenExpired,
|
|
610
616
|
ErrForbidden,
|
|
611
617
|
ErrNotFound,
|
|
618
|
+
ErrNeedsHints,
|
|
612
619
|
ErrUnsupportedPci,
|
|
613
620
|
// /client thrown directly by `create()`
|
|
614
621
|
ErrMalformedAccessToken,
|
|
@@ -654,6 +661,8 @@ import {
|
|
|
654
661
|
| `ErrTokenExpired` | HTTP 401 with token-expired detail |
|
|
655
662
|
| `ErrForbidden` | HTTP 403 |
|
|
656
663
|
| `ErrNotFound` | HTTP 404 |
|
|
664
|
+
| `ErrNeedsHints` | HTTP 412 — the student has no `gradeLevel` on record; backend must call `setStudentHints` and mint a fresh access token |
|
|
665
|
+
| `ErrSdkUpgradeRequired` | the SDK's version is older than the server's minimum-supported version; bump `@superbuilders/primer-tives` to the latest |
|
|
657
666
|
| `ErrUnsupportedPci` | HTTP 422 or a frame asks for a PCI not in `supportedPcis` |
|
|
658
667
|
|
|
659
668
|
## Thrown directly by `create()`
|
|
@@ -714,7 +723,7 @@ interface PrimerLogger {
|
|
|
714
723
|
}
|
|
715
724
|
```
|
|
716
725
|
|
|
717
|
-
Required by `PrimerServerConfig
|
|
726
|
+
Required by both `PrimerServerConfig` and `Config` (the client config). The SDK never silently swallows operational events — every fatal, parse failure, transport error, and submission rejection goes through this logger. `@superbuilders/slog` matches this shape directly — `import * as logger from "@superbuilders/slog"` and pass `logger`.
|
|
718
727
|
|
|
719
728
|
---
|
|
720
729
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { ContentBlock } from "../contracts/content";
|
|
1
2
|
import type { SessionContext } from "./session-context";
|
|
2
3
|
import type { PciId } from "../contracts/pci";
|
|
3
4
|
import type { RendererChoice, RendererInteraction, RendererStimulus } from "../contracts/types";
|
|
4
5
|
import type { PrimerState } from "./types";
|
|
5
|
-
declare function choiceState<Pcis extends PciId>(ctx: SessionContext<Pcis>, stimulus: RendererStimulus | null, interaction: Extract<RendererInteraction<Pcis>, {
|
|
6
|
+
declare function choiceState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: Extract<RendererInteraction<Pcis>, {
|
|
6
7
|
type: "choice";
|
|
7
8
|
}>, options: RendererChoice[], maxChoices: number, minChoices: number): PrimerState<Pcis>;
|
|
8
9
|
export { choiceState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choice-state.d.ts","sourceRoot":"","sources":["../../src/client/choice-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"choice-state.d.ts","sourceRoot":"","sources":["../../src/client/choice-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AAOjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,MAAM,6CAA6C,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAG3E,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"}
|
package/dist/client/create.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ interface Config<Pcis extends PciId = PciId> {
|
|
|
9
9
|
readonly subject: SubjectScope;
|
|
10
10
|
readonly fetch?: typeof globalThis.fetch;
|
|
11
11
|
readonly abort?: AbortController;
|
|
12
|
-
readonly logger
|
|
12
|
+
readonly logger: PrimerLogger;
|
|
13
13
|
}
|
|
14
14
|
interface Client<Pcis extends PciId = PciId> {
|
|
15
15
|
start(): Promise<PrimerState<Pcis>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/client/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAA;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAM3E,UAAU,MAAM,CAAC,IAAI,SAAS,KAAK,GAAG,KAAK;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,SAAS,IAAI,EAAE,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/client/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAA;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAM3E,UAAU,MAAM,CAAC,IAAI,SAAS,KAAK,GAAG,KAAK;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,SAAS,IAAI,EAAE,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B;AAED,UAAU,MAAM,CAAC,IAAI,SAAS,KAAK,GAAG,KAAK;IAC1C,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;CACnC;AAUD,iBAAS,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CA2C5E;AAED,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { ContentBlock } from "../contracts/content";
|
|
1
2
|
import type { SessionContext } from "./session-context";
|
|
2
3
|
import type { PciId } from "../contracts/pci";
|
|
3
4
|
import type { RendererStimulus, StandardRendererInteraction } from "../contracts/types";
|
|
4
5
|
import type { PrimerState } from "./types";
|
|
5
|
-
declare function extendedTextState<Pcis extends PciId>(ctx: SessionContext<Pcis>, stimulus: RendererStimulus | null, interaction: Extract<StandardRendererInteraction, {
|
|
6
|
+
declare function extendedTextState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: Extract<StandardRendererInteraction, {
|
|
6
7
|
type: "extended-text";
|
|
7
8
|
}>): PrimerState<Pcis>;
|
|
8
9
|
export { extendedTextState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extended-text-state.d.ts","sourceRoot":"","sources":["../../src/client/extended-text-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extended-text-state.d.ts","sourceRoot":"","sources":["../../src/client/extended-text-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAA;AAOjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,gBAAgB,EAChB,2BAA2B,EAC3B,MAAM,6CAA6C,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAG3E,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,9 +1,9 @@
|
|
|
1
|
-
import type { ContentInline } from "../contracts/content";
|
|
1
|
+
import type { ContentBlock, ContentInline } from "../contracts/content";
|
|
2
2
|
import type { SessionContext } from "./session-context";
|
|
3
3
|
import type { PciId } from "../contracts/pci";
|
|
4
4
|
import type { RendererInteraction, RendererStimulus, RendererSubmission } from "../contracts/types";
|
|
5
5
|
import type { InteractionReview } from "../contracts/review";
|
|
6
6
|
import type { PrimerState } from "./types";
|
|
7
|
-
declare function feedbackState<Pcis extends PciId>(ctx: SessionContext<Pcis>, stimulus: RendererStimulus | null, interaction: RendererInteraction<Pcis>, submission: RendererSubmission<Pcis>, isCorrect: boolean, feedbackContent: ContentInline[], review: InteractionReview<Pcis> | null): PrimerState<Pcis>;
|
|
7
|
+
declare function feedbackState<Pcis extends PciId>(ctx: SessionContext<Pcis>, body: ContentBlock[], stimulus: RendererStimulus | null, interaction: RendererInteraction<Pcis>, submission: RendererSubmission<Pcis>, isCorrect: boolean, feedbackContent: ContentInline[], review: InteractionReview<Pcis> | null): PrimerState<Pcis>;
|
|
8
8
|
export { feedbackState };
|
|
9
9
|
//# 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,aAAa,EAAE,MAAM,+CAA+C,CAAA;
|
|
1
|
+
{"version":3,"file":"feedback-state.d.ts","sourceRoot":"","sources":["../../src/client/feedback-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,+CAA+C,CAAA;AAChG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACxF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EACX,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,6CAA6C,CAAA;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAA;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAA;AAE3E,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,SAAS,EAAE,OAAO,EAClB,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"}
|