@superbuilders/primer-tives 0.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 +344 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +383 -0
- package/dist/client.js.map +11 -0
- package/dist/content.d.ts +16 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +27 -0
- package/dist/content.js.map +10 -0
- package/dist/errors.d.ts +17 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +36 -0
- package/dist/errors.js.map +10 -0
- package/dist/pci.d.ts +38 -0
- package/dist/pci.d.ts.map +1 -0
- package/dist/pci.js +2 -0
- package/dist/pci.js.map +9 -0
- package/dist/types.d.ts +188 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +9 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# @superbuilders/primer-tives
|
|
2
|
+
|
|
3
|
+
Client SDK for the Primer adaptive learning engine. Drives a state machine over HTTP POST — the client renders frames, the server controls all routing and assessment.
|
|
4
|
+
|
|
5
|
+
The SDK has no concept of routines, curricula, or backend storage structure. It advances a student through whatever the server decides to serve next.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
bun add @superbuilders/primer-tives
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Dependency: `@superbuilders/errors` is installed automatically.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { create } from "@superbuilders/primer-tives/client"
|
|
19
|
+
import * as errors from "@superbuilders/errors"
|
|
20
|
+
import { ErrNetwork, ErrRateLimited } from "@superbuilders/primer-tives/errors"
|
|
21
|
+
|
|
22
|
+
const client = create({
|
|
23
|
+
publishableKey: "pk_live_abc123",
|
|
24
|
+
supportedPcis: ["urn:primer:pci:division-remainder"],
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
let state = await client.start("student-uuid")
|
|
28
|
+
|
|
29
|
+
while (state.phase !== "completed" && state.phase !== "fatal") {
|
|
30
|
+
switch (state.phase) {
|
|
31
|
+
case "observation":
|
|
32
|
+
renderStimulus(state.stimulus)
|
|
33
|
+
state = await state.advance()
|
|
34
|
+
break
|
|
35
|
+
|
|
36
|
+
case "interaction":
|
|
37
|
+
switch (state.kind) {
|
|
38
|
+
case "choice":
|
|
39
|
+
state = await state.submitChoice(["option-a"])
|
|
40
|
+
break
|
|
41
|
+
case "text-entry":
|
|
42
|
+
state = await state.submitText("42")
|
|
43
|
+
break
|
|
44
|
+
case "extended-text":
|
|
45
|
+
if (state.cardinality === "single") {
|
|
46
|
+
state = await state.submitText("answer")
|
|
47
|
+
} else {
|
|
48
|
+
state = await state.submitTexts(["a", "b"])
|
|
49
|
+
}
|
|
50
|
+
break
|
|
51
|
+
case "portable-custom":
|
|
52
|
+
state = await state.submit({ quotient: "3", remainder: "1" })
|
|
53
|
+
break
|
|
54
|
+
}
|
|
55
|
+
break
|
|
56
|
+
|
|
57
|
+
case "feedback":
|
|
58
|
+
renderFeedback(state.isCorrect, state.feedbackContent, state.correctAnswer)
|
|
59
|
+
state = await state.advance()
|
|
60
|
+
break
|
|
61
|
+
|
|
62
|
+
case "errored":
|
|
63
|
+
if (errors.is(state.error, ErrRateLimited)) {
|
|
64
|
+
await delay(1000)
|
|
65
|
+
}
|
|
66
|
+
state = await state.retry()
|
|
67
|
+
break
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Wire protocol
|
|
73
|
+
|
|
74
|
+
Every request is a POST to `https://${origin}/api/v0/advance`:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
POST /api/v0/advance
|
|
78
|
+
Header: X-Primer-Publishable-Key: pk_...
|
|
79
|
+
Body: { studentId, supportedPcis, intent }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
When `origin` is omitted, the SDK uses a relative path (`/api/v0/advance`) for same-origin requests. For cross-origin integrations, set `origin` to the Primer API host (e.g., `https://sb-primer.vercel.app`). The path constant `ADVANCE_PATH` is exported for reference.
|
|
83
|
+
|
|
84
|
+
The server identifies the student, determines which content to serve, evaluates submissions, and returns the next frame. The client never sends routing information — it only sends:
|
|
85
|
+
|
|
86
|
+
- `studentId` — who is being advanced
|
|
87
|
+
- `supportedPcis` — which custom interaction types the renderer can handle
|
|
88
|
+
- `intent` — `{ kind: "observation" }` or `{ kind: "interaction", submission: ... }`
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
interface Config<Pcis extends PciId = PciId> {
|
|
94
|
+
readonly publishableKey: string
|
|
95
|
+
readonly supportedPcis: readonly Pcis[]
|
|
96
|
+
readonly origin?: string
|
|
97
|
+
readonly fetch?: typeof globalThis.fetch
|
|
98
|
+
readonly abort?: AbortController
|
|
99
|
+
readonly logger?: PrimerLogger
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
| Field | Required | Description |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `publishableKey` | yes | Must start with `pk_`. Sent as `X-Primer-Publishable-Key` header |
|
|
106
|
+
| `supportedPcis` | yes | PCI URNs the renderer handles. `[]` if none |
|
|
107
|
+
| `origin` | no | Origin URL for cross-origin requests. Omit for same-origin (relative fetch). Required for third-party integrations |
|
|
108
|
+
| `fetch` | no | Custom fetch. Defaults to `globalThis.fetch` |
|
|
109
|
+
| `abort` | no | AbortController for cancelling in-flight requests |
|
|
110
|
+
| `logger` | no | Structured logger (`debug`, `info`, `warn`, `error`) |
|
|
111
|
+
|
|
112
|
+
`create()` validates the key prefix immediately — throws `ErrMalformedPublishableKey` if invalid.
|
|
113
|
+
|
|
114
|
+
## State machine
|
|
115
|
+
|
|
116
|
+
`PrimerState` is a discriminated union on `phase`:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
observation → interaction → feedback → observation → ... → completed
|
|
120
|
+
↓ ↓
|
|
121
|
+
errored errored
|
|
122
|
+
↓
|
|
123
|
+
(retry) → back to failed phase
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `observation`
|
|
127
|
+
|
|
128
|
+
Display-only frame. Show the stimulus, call `advance()`.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
state.stimulus // RendererStimulus | null
|
|
132
|
+
state.advance() // Promise<PrimerState>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Stimulus is a discriminated union on `type`:
|
|
136
|
+
- `BodyStimulus` — `{ type: "body", body: ContentBlock[] }` — text-only
|
|
137
|
+
- `ImageStimulus` — `{ type: "image", description: ContentInline[], src: string }` — image-backed
|
|
138
|
+
- `null` — no stimulus
|
|
139
|
+
|
|
140
|
+
### `interaction`
|
|
141
|
+
|
|
142
|
+
Student must respond. Discriminate on `state.kind`:
|
|
143
|
+
|
|
144
|
+
| `state.kind` | Submit | Key fields |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `"choice"` | `submitChoice(keys: string[])` | `options`, `maxChoices`, `minChoices` |
|
|
147
|
+
| `"text-entry"` | `submitText(value: string)` | — |
|
|
148
|
+
| `"extended-text"` (single) | `submitText(value: string)` | `cardinality: "single"` |
|
|
149
|
+
| `"extended-text"` (multiple) | `submitTexts(values: string[])` | `cardinality: "multiple"`, `maxStrings`, `minStrings` |
|
|
150
|
+
| `"portable-custom"` | `submit(value: PciValue<K>)` | `pciId`, `properties` |
|
|
151
|
+
|
|
152
|
+
All submit methods return `Promise<PrimerState>`.
|
|
153
|
+
|
|
154
|
+
### `feedback`
|
|
155
|
+
|
|
156
|
+
Server evaluated the submission. Show result, call `advance()`.
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
state.stimulus // RendererStimulus | null
|
|
160
|
+
state.interaction // the original interaction
|
|
161
|
+
state.submission // the student's submission
|
|
162
|
+
state.isCorrect // boolean
|
|
163
|
+
state.feedbackContent // ContentInline[]
|
|
164
|
+
state.correctAnswer // RendererCorrectAnswer | null
|
|
165
|
+
state.advance() // Promise<PrimerState>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`correctAnswer` carries the canonical correct response, or `null` when unavailable:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
type RendererCorrectScalarValue =
|
|
172
|
+
| { kind: "identifier"; value: string }
|
|
173
|
+
| { kind: "string"; value: string }
|
|
174
|
+
| { kind: "integer"; value: number }
|
|
175
|
+
| { kind: "float"; value: number }
|
|
176
|
+
|
|
177
|
+
type RendererCorrectAnswer =
|
|
178
|
+
| { kind: "single"; value: RendererCorrectScalarValue | null }
|
|
179
|
+
| { kind: "multiple"; values: RendererCorrectScalarValue[] }
|
|
180
|
+
| {
|
|
181
|
+
kind: "record"
|
|
182
|
+
fields: Array<{
|
|
183
|
+
fieldIdentifier: string
|
|
184
|
+
baseType: "identifier" | "string" | "integer" | "float"
|
|
185
|
+
value: RendererCorrectScalarValue | null
|
|
186
|
+
}>
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
For choice interactions, extract correct option identifiers from `kind: "identifier"` scalars. For text-entry, check `kind: "string"` or `kind: "integer"`. For PCI record responses, iterate `fields`. `null` means the server could not determine a correct response.
|
|
191
|
+
|
|
192
|
+
### `completed`
|
|
193
|
+
|
|
194
|
+
Session finished. No further actions.
|
|
195
|
+
|
|
196
|
+
### `errored`
|
|
197
|
+
|
|
198
|
+
Retryable error (network, timeout, rate limit, 5xx). Remembers the failed intent.
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
state.error // Error sentinel (use errors.is())
|
|
202
|
+
state.failedPhase // "observation" | "interaction"
|
|
203
|
+
state.retry() // Promise<PrimerState> — replays exact failed intent
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `fatal`
|
|
207
|
+
|
|
208
|
+
Terminal. Unsupported PCI or unknown interaction type. Session is broken.
|
|
209
|
+
|
|
210
|
+
## Stimulus & Interaction
|
|
211
|
+
|
|
212
|
+
Every state carries a `stimulus: RendererStimulus | null` directly:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
state.stimulus // RendererStimulus | null
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Stimulus is a discriminated union on `type`:
|
|
219
|
+
- `BodyStimulus` — `{ type: "body", body: ContentBlock[] }` — text-only
|
|
220
|
+
- `ImageStimulus` — `{ type: "image", description: ContentInline[], src: string }` — image-backed
|
|
221
|
+
- `null` — no stimulus
|
|
222
|
+
|
|
223
|
+
Interaction states also carry `interaction` directly:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
state.interaction.prompt // ContentInline[]
|
|
227
|
+
state.interaction.type // "choice" | "text-entry" | "extended-text" | "portable-custom"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Client-side validation
|
|
231
|
+
|
|
232
|
+
The SDK validates submissions before sending them to the server:
|
|
233
|
+
|
|
234
|
+
**Choice:** rejects fewer than `minChoices`, more than `maxChoices`, duplicates, unknown option identifiers.
|
|
235
|
+
|
|
236
|
+
**Extended text (multiple):** rejects fewer than `minStrings`, more than `maxStrings`.
|
|
237
|
+
|
|
238
|
+
Failed validation returns an `errored` state with `ErrInvalidSubmission`.
|
|
239
|
+
|
|
240
|
+
## Error sentinels
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import * as errors from "@superbuilders/errors"
|
|
244
|
+
import { ErrNetwork, ErrRateLimited } from "@superbuilders/primer-tives/errors"
|
|
245
|
+
|
|
246
|
+
if (errors.is(state.error, ErrNetwork)) { /* handle */ }
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
| Sentinel | Cause |
|
|
250
|
+
|---|---|
|
|
251
|
+
| `ErrNetwork` | Fetch failed (offline, DNS, CORS) |
|
|
252
|
+
| `ErrTimeout` | Request aborted or timed out |
|
|
253
|
+
| `ErrJsonParse` | Response not valid JSON |
|
|
254
|
+
| `ErrBadRequest` | 400 |
|
|
255
|
+
| `ErrInvalidPublishableKey` | 401 |
|
|
256
|
+
| `ErrForbidden` | 403 |
|
|
257
|
+
| `ErrNotFound` | 404 |
|
|
258
|
+
| `ErrConflict` | 409 |
|
|
259
|
+
| `ErrUnsupportedPci` | 422 — server sent a PCI the client can't handle |
|
|
260
|
+
| `ErrRateLimited` | 429 |
|
|
261
|
+
| `ErrServerError` | 5xx |
|
|
262
|
+
| `ErrServiceUnavailable` | 502/503/504 |
|
|
263
|
+
| `ErrInvalidSubmission` | Client-side validation failed |
|
|
264
|
+
| `ErrNotSerializable` | Attempted to JSON.stringify PrimerState |
|
|
265
|
+
| `ErrMalformedPublishableKey` | Key doesn't start with `pk_` |
|
|
266
|
+
|
|
267
|
+
**`errored`** = retryable (call `retry()`). **`fatal`** = terminal.
|
|
268
|
+
|
|
269
|
+
## Submission payloads
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
type RendererSubmission<K extends PciId = PciId> =
|
|
273
|
+
| { type: "choice"; selectedKeys: string[] }
|
|
274
|
+
| { type: "text-entry"; value: string }
|
|
275
|
+
| { type: "extended-text"; values: string[] }
|
|
276
|
+
| { type: "portable-custom"; pciId: K; value: PciValue<K> }
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
See `/types` for the full type surface.
|
|
280
|
+
|
|
281
|
+
## Content format
|
|
282
|
+
|
|
283
|
+
Minimal example of the content format:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
type ContentInline =
|
|
287
|
+
| { type: "text"; value: string }
|
|
288
|
+
| { type: "italic"; children: ContentInline[] }
|
|
289
|
+
|
|
290
|
+
type ContentBlock = { type: "paragraph"; children: ContentInline[] }
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
`inlinesToPlainText(nodes)` strips inline formatting for accessibility labels. `blocksToPlainText(blocks)` flattens blocks to plain text. See `/content` for the complete type surface.
|
|
294
|
+
|
|
295
|
+
## PCI system
|
|
296
|
+
|
|
297
|
+
Portable Custom Interactions handle domain-specific input types with full type safety.
|
|
298
|
+
|
|
299
|
+
### Registry
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
interface PciRegistry {
|
|
303
|
+
"urn:primer:pci:division-remainder": {
|
|
304
|
+
props: { dividend: number; divisor: number }
|
|
305
|
+
value: { quotient: string; remainder: string }
|
|
306
|
+
}
|
|
307
|
+
"urn:primer:pci:fraction-addition": {
|
|
308
|
+
props: {
|
|
309
|
+
left: { numerator: number; denominator: number }
|
|
310
|
+
right: { numerator: number; denominator: number }
|
|
311
|
+
}
|
|
312
|
+
value: { numerator: string; denominator: string }
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Type helpers
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
type PciId = keyof PciRegistry & string
|
|
321
|
+
type PciProps<K extends PciId> // server-provided props
|
|
322
|
+
type PciValue<K extends PciId> // submission value
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Adding a PCI
|
|
326
|
+
|
|
327
|
+
1. Add entry to `PciRegistry` in `src/pci.ts`
|
|
328
|
+
2. URN format: `urn:primer:pci:<name>`
|
|
329
|
+
3. Include in `supportedPcis` when calling `create()`
|
|
330
|
+
4. Build renderer with `PciRenderProps<"urn:primer:pci:your-pci">`
|
|
331
|
+
|
|
332
|
+
## Subpath exports
|
|
333
|
+
|
|
334
|
+
| Path | JS | Description |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| `/client` | yes | `create()`, transport, state machine |
|
|
337
|
+
| `/types` | yes | States, interactions, submissions, `PciRenderProps` |
|
|
338
|
+
| `/content` | yes | `ContentInline`, `inlinesToPlainText()` |
|
|
339
|
+
| `/errors` | yes | 15 sentinel error constants |
|
|
340
|
+
| `/pci` | yes | `PciId`, `PciProps`, `PciValue`, `PciRegistry` |
|
|
341
|
+
|
|
342
|
+
## Non-serializable state
|
|
343
|
+
|
|
344
|
+
`PrimerState` contains closures. Every state object has a poisoned `toJSON()` that throws `ErrNotSerializable`. Do not persist, stringify, or transfer `PrimerState` — it is ephemeral in-memory state.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PciId } from "./pci";
|
|
2
|
+
import type { PrimerState } from "./types";
|
|
3
|
+
interface PrimerLogger {
|
|
4
|
+
debug(message: string, attributes?: Record<string, unknown>): void;
|
|
5
|
+
info(message: string, attributes?: Record<string, unknown>): void;
|
|
6
|
+
warn(message: string, attributes?: Record<string, unknown>): void;
|
|
7
|
+
error(message: string, attributes?: Record<string, unknown>): void;
|
|
8
|
+
}
|
|
9
|
+
declare const DEFAULT_ORIGIN = "https://sb-primer.vercel.app";
|
|
10
|
+
declare const ADVANCE_PATH = "/api/v0/advance";
|
|
11
|
+
interface Config<Pcis extends PciId = PciId> {
|
|
12
|
+
readonly publishableKey: string;
|
|
13
|
+
readonly supportedPcis: readonly Pcis[];
|
|
14
|
+
readonly origin?: string;
|
|
15
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
16
|
+
readonly abort?: AbortController;
|
|
17
|
+
readonly logger?: PrimerLogger;
|
|
18
|
+
}
|
|
19
|
+
interface Client<Pcis extends PciId = PciId> {
|
|
20
|
+
start(studentId: string): Promise<PrimerState<Pcis>>;
|
|
21
|
+
}
|
|
22
|
+
declare function create<const Pcis extends PciId>(config: Config<Pcis>): Client<Pcis>;
|
|
23
|
+
export { ADVANCE_PATH, DEFAULT_ORIGIN, create };
|
|
24
|
+
export type { Client, Config, PrimerLogger };
|
|
25
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,KAAK,EAAY,MAAM,iCAAiC,CAAA;AACtE,OAAO,KAAK,EAIX,WAAW,EAMX,MAAM,mCAAmC,CAAA;AAG1C,UAAU,YAAY;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAClE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAClE;AAiCD,QAAA,MAAM,cAAc,iCAAiC,CAAA;AACrD,QAAA,MAAM,YAAY,oBAAoB,CAAA;AAEtC,UAAU,MAAM,CAAC,IAAI,SAAS,KAAK,GAAG,KAAK;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,SAAS,IAAI,EAAE,CAAA;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAC9B;AAED,UAAU,MAAM,CAAC,IAAI,SAAS,KAAK,GAAG,KAAK;IAC1C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;CACpD;AA+CD,iBAAS,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAmb5E;AAED,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,EAAE,CAAA;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
import * as errors from "@superbuilders/errors";
|
|
3
|
+
var ErrNetwork = errors.new("network");
|
|
4
|
+
var ErrJsonParse = errors.new("json parse");
|
|
5
|
+
var ErrUnsupportedPci = errors.new("unsupported pci");
|
|
6
|
+
var ErrInvalidPublishableKey = errors.new("invalid publishable key");
|
|
7
|
+
var ErrBadRequest = errors.new("bad request");
|
|
8
|
+
var ErrServerError = errors.new("server error");
|
|
9
|
+
var ErrTimeout = errors.new("timeout");
|
|
10
|
+
var ErrForbidden = errors.new("forbidden");
|
|
11
|
+
var ErrNotFound = errors.new("not found");
|
|
12
|
+
var ErrConflict = errors.new("conflict");
|
|
13
|
+
var ErrRateLimited = errors.new("rate limited");
|
|
14
|
+
var ErrServiceUnavailable = errors.new("service unavailable");
|
|
15
|
+
var ErrNotSerializable = errors.new("PrimerState is live in-memory state and must not be serialized or stored");
|
|
16
|
+
var ErrInvalidSubmission = errors.new("invalid submission");
|
|
17
|
+
var ErrMalformedPublishableKey = errors.new("malformed publishable key");
|
|
18
|
+
// src/client.ts
|
|
19
|
+
import * as errors2 from "@superbuilders/errors";
|
|
20
|
+
var DEFAULT_ORIGIN = "https://sb-primer.vercel.app";
|
|
21
|
+
var ADVANCE_PATH = "/api/v0/advance";
|
|
22
|
+
function poisonToJSON() {
|
|
23
|
+
throw ErrNotSerializable;
|
|
24
|
+
}
|
|
25
|
+
function httpSentinel(status) {
|
|
26
|
+
if (status === 400) {
|
|
27
|
+
return ErrBadRequest;
|
|
28
|
+
}
|
|
29
|
+
if (status === 401) {
|
|
30
|
+
return ErrInvalidPublishableKey;
|
|
31
|
+
}
|
|
32
|
+
if (status === 403) {
|
|
33
|
+
return ErrForbidden;
|
|
34
|
+
}
|
|
35
|
+
if (status === 404) {
|
|
36
|
+
return ErrNotFound;
|
|
37
|
+
}
|
|
38
|
+
if (status === 409) {
|
|
39
|
+
return ErrConflict;
|
|
40
|
+
}
|
|
41
|
+
if (status === 422) {
|
|
42
|
+
return ErrUnsupportedPci;
|
|
43
|
+
}
|
|
44
|
+
if (status === 429) {
|
|
45
|
+
return ErrRateLimited;
|
|
46
|
+
}
|
|
47
|
+
if (status === 502 || status === 503 || status === 504) {
|
|
48
|
+
return ErrServiceUnavailable;
|
|
49
|
+
}
|
|
50
|
+
return ErrServerError;
|
|
51
|
+
}
|
|
52
|
+
function isAbortError(err) {
|
|
53
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
var PK_PREFIX = "pk_";
|
|
62
|
+
function create(config) {
|
|
63
|
+
const configFetch = config.fetch;
|
|
64
|
+
const fetchFn = configFetch ? configFetch : globalThis.fetch;
|
|
65
|
+
const log = config.logger;
|
|
66
|
+
if (!config.publishableKey.startsWith(PK_PREFIX)) {
|
|
67
|
+
log?.error("malformed publishable key", { prefix: PK_PREFIX });
|
|
68
|
+
throw errors2.wrap(ErrMalformedPublishableKey, `key must start with '${PK_PREFIX}'`);
|
|
69
|
+
}
|
|
70
|
+
function transportSignal() {
|
|
71
|
+
if (config.abort) {
|
|
72
|
+
return config.abort.signal;
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
async function transport(body) {
|
|
77
|
+
log?.debug("transport request", {
|
|
78
|
+
studentId: body.studentId,
|
|
79
|
+
intentKind: body.intent.kind
|
|
80
|
+
});
|
|
81
|
+
const url = config.origin ? `${config.origin}${ADVANCE_PATH}` : ADVANCE_PATH;
|
|
82
|
+
const fetchResult = await fetchFn(url, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: {
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
"X-Primer-Publishable-Key": config.publishableKey
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify(body),
|
|
89
|
+
signal: transportSignal()
|
|
90
|
+
}).then(function ok(r) {
|
|
91
|
+
return { ok: true, response: r };
|
|
92
|
+
}, function fail(err) {
|
|
93
|
+
return { ok: false, error: err };
|
|
94
|
+
});
|
|
95
|
+
if (!fetchResult.ok) {
|
|
96
|
+
if (isAbortError(fetchResult.error)) {
|
|
97
|
+
log?.error("transport timeout", {
|
|
98
|
+
studentId: body.studentId,
|
|
99
|
+
intentKind: body.intent.kind
|
|
100
|
+
});
|
|
101
|
+
return { ok: false, error: errors2.wrap(ErrTimeout, fetchResult.error.message) };
|
|
102
|
+
}
|
|
103
|
+
log?.error("transport network error", {
|
|
104
|
+
studentId: body.studentId,
|
|
105
|
+
error: fetchResult.error
|
|
106
|
+
});
|
|
107
|
+
return { ok: false, error: errors2.wrap(ErrNetwork, fetchResult.error.message) };
|
|
108
|
+
}
|
|
109
|
+
const res = fetchResult.response;
|
|
110
|
+
if (!res.ok) {
|
|
111
|
+
const text = await res.text().catch(function fallback() {
|
|
112
|
+
return "";
|
|
113
|
+
});
|
|
114
|
+
const sentinel = httpSentinel(res.status);
|
|
115
|
+
log?.error("transport http error", {
|
|
116
|
+
studentId: body.studentId,
|
|
117
|
+
status: res.status
|
|
118
|
+
});
|
|
119
|
+
return { ok: false, error: errors2.wrap(sentinel, text) };
|
|
120
|
+
}
|
|
121
|
+
const jsonResult = await res.json().then(function ok(data) {
|
|
122
|
+
return { ok: true, data };
|
|
123
|
+
}, function fail(err) {
|
|
124
|
+
return { ok: false, error: err };
|
|
125
|
+
});
|
|
126
|
+
if (!jsonResult.ok) {
|
|
127
|
+
log?.error("transport json parse failed", {
|
|
128
|
+
studentId: body.studentId,
|
|
129
|
+
error: jsonResult.error
|
|
130
|
+
});
|
|
131
|
+
return { ok: false, error: errors2.wrap(ErrJsonParse, jsonResult.error.message) };
|
|
132
|
+
}
|
|
133
|
+
log?.debug("transport success", {
|
|
134
|
+
studentId: body.studentId,
|
|
135
|
+
intentKind: body.intent.kind
|
|
136
|
+
});
|
|
137
|
+
return { ok: true, data: jsonResult.data };
|
|
138
|
+
}
|
|
139
|
+
function makeSession(studentId) {
|
|
140
|
+
function resolve(result) {
|
|
141
|
+
switch (result.outcome) {
|
|
142
|
+
case "advanced":
|
|
143
|
+
return fromAdvanced(result.stimulus, result.interaction);
|
|
144
|
+
case "submitted":
|
|
145
|
+
return feedbackState(result.stimulus, result.interaction, result.submission, result.isCorrect, result.feedbackContent, result.correctAnswer);
|
|
146
|
+
case "completed":
|
|
147
|
+
return { phase: "completed", toJSON: poisonToJSON };
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function errored(error, failedPhase, intent) {
|
|
151
|
+
return {
|
|
152
|
+
phase: "errored",
|
|
153
|
+
error,
|
|
154
|
+
failedPhase,
|
|
155
|
+
retry: function retry() {
|
|
156
|
+
log?.debug("retrying from errored state", { failedPhase });
|
|
157
|
+
return execute(intent, failedPhase);
|
|
158
|
+
},
|
|
159
|
+
toJSON: poisonToJSON
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
async function execute(intent, phase) {
|
|
163
|
+
const body = {
|
|
164
|
+
studentId,
|
|
165
|
+
supportedPcis: config.supportedPcis,
|
|
166
|
+
intent
|
|
167
|
+
};
|
|
168
|
+
const result = await transport(body);
|
|
169
|
+
if (!result.ok) {
|
|
170
|
+
return errored(result.error, phase, intent);
|
|
171
|
+
}
|
|
172
|
+
return resolve(result.data);
|
|
173
|
+
}
|
|
174
|
+
function isPciSupported(pciId) {
|
|
175
|
+
for (const id of config.supportedPcis) {
|
|
176
|
+
if (id === pciId) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
function fromAdvanced(stimulus, interaction) {
|
|
183
|
+
if (interaction === null) {
|
|
184
|
+
return observationState(stimulus);
|
|
185
|
+
}
|
|
186
|
+
if (interaction.type === "portable-custom") {
|
|
187
|
+
if (!isPciSupported(interaction.pciId)) {
|
|
188
|
+
log?.error("unsupported pci in frame", { pciId: interaction.pciId });
|
|
189
|
+
return {
|
|
190
|
+
phase: "fatal",
|
|
191
|
+
error: errors2.wrap(ErrUnsupportedPci, `pci '${interaction.pciId}'`),
|
|
192
|
+
toJSON: poisonToJSON
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return pendingInteractionState(stimulus, interaction);
|
|
197
|
+
}
|
|
198
|
+
function observationState(stimulus) {
|
|
199
|
+
return {
|
|
200
|
+
phase: "observation",
|
|
201
|
+
stimulus,
|
|
202
|
+
advance: function advance() {
|
|
203
|
+
return execute({ kind: "observation" }, "observation");
|
|
204
|
+
},
|
|
205
|
+
toJSON: poisonToJSON
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function pendingInteractionState(stimulus, interaction) {
|
|
209
|
+
switch (interaction.type) {
|
|
210
|
+
case "choice":
|
|
211
|
+
return choiceState(stimulus, interaction, interaction.options, interaction.maxChoices, interaction.minChoices);
|
|
212
|
+
case "text-entry":
|
|
213
|
+
return textEntryState(stimulus, interaction);
|
|
214
|
+
case "extended-text":
|
|
215
|
+
return extendedTextState(stimulus, interaction);
|
|
216
|
+
case "portable-custom":
|
|
217
|
+
return pciInteractionState(stimulus, interaction);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function findUnknownKey(selectedKeys, options) {
|
|
221
|
+
const optionIds = new Set(options.map(function getId(o) {
|
|
222
|
+
return o.identifier;
|
|
223
|
+
}));
|
|
224
|
+
for (const key of selectedKeys) {
|
|
225
|
+
if (!optionIds.has(key)) {
|
|
226
|
+
return key;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
function validateChoiceSubmission(selectedKeys, options, maxChoices, minChoices) {
|
|
232
|
+
if (selectedKeys.length < minChoices) {
|
|
233
|
+
log?.error("choice submit below minChoices", { selectedKeys, minChoices });
|
|
234
|
+
return errors2.wrap(ErrInvalidSubmission, `need at least ${minChoices} selections`);
|
|
235
|
+
}
|
|
236
|
+
if (selectedKeys.length > maxChoices) {
|
|
237
|
+
log?.error("choice submit above maxChoices", { selectedKeys, maxChoices });
|
|
238
|
+
return errors2.wrap(ErrInvalidSubmission, `at most ${maxChoices} selections`);
|
|
239
|
+
}
|
|
240
|
+
const uniqueKeys = new Set(selectedKeys);
|
|
241
|
+
if (uniqueKeys.size !== selectedKeys.length) {
|
|
242
|
+
log?.error("choice submit has duplicates", { selectedKeys });
|
|
243
|
+
return errors2.wrap(ErrInvalidSubmission, "duplicate selections");
|
|
244
|
+
}
|
|
245
|
+
const unknownKey = findUnknownKey(selectedKeys, options);
|
|
246
|
+
if (unknownKey) {
|
|
247
|
+
log?.error("choice submit has unknown key", { key: unknownKey });
|
|
248
|
+
return errors2.wrap(ErrInvalidSubmission, `unknown option '${unknownKey}'`);
|
|
249
|
+
}
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
function choiceState(stimulus, interaction, options, maxChoices, minChoices) {
|
|
253
|
+
return {
|
|
254
|
+
phase: "interaction",
|
|
255
|
+
kind: "choice",
|
|
256
|
+
stimulus,
|
|
257
|
+
interaction,
|
|
258
|
+
options,
|
|
259
|
+
maxChoices,
|
|
260
|
+
minChoices,
|
|
261
|
+
submitChoice: function submitChoice(selectedKeys) {
|
|
262
|
+
const validationError = validateChoiceSubmission(selectedKeys, options, maxChoices, minChoices);
|
|
263
|
+
if (validationError) {
|
|
264
|
+
return Promise.resolve(errored(validationError, "interaction", {
|
|
265
|
+
kind: "interaction",
|
|
266
|
+
submission: { type: "choice", selectedKeys }
|
|
267
|
+
}));
|
|
268
|
+
}
|
|
269
|
+
return execute({ kind: "interaction", submission: { type: "choice", selectedKeys } }, "interaction");
|
|
270
|
+
},
|
|
271
|
+
toJSON: poisonToJSON
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function textEntryState(stimulus, interaction) {
|
|
275
|
+
return {
|
|
276
|
+
phase: "interaction",
|
|
277
|
+
kind: "text-entry",
|
|
278
|
+
stimulus,
|
|
279
|
+
interaction,
|
|
280
|
+
submitText: function submitText(value) {
|
|
281
|
+
return execute({ kind: "interaction", submission: { type: "text-entry", value } }, "interaction");
|
|
282
|
+
},
|
|
283
|
+
toJSON: poisonToJSON
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function validateExtendedTextSubmission(values, minStrings, maxStrings) {
|
|
287
|
+
if (values.length < minStrings) {
|
|
288
|
+
log?.error("extended-text submit below minStrings", { count: values.length, minStrings });
|
|
289
|
+
return errors2.wrap(ErrInvalidSubmission, `need at least ${minStrings} values`);
|
|
290
|
+
}
|
|
291
|
+
if (values.length > maxStrings) {
|
|
292
|
+
log?.error("extended-text submit above maxStrings", { count: values.length, maxStrings });
|
|
293
|
+
return errors2.wrap(ErrInvalidSubmission, `at most ${maxStrings} values`);
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
function extendedTextState(stimulus, interaction) {
|
|
298
|
+
const maxStrings = interaction.maxStrings;
|
|
299
|
+
const minStrings = interaction.minStrings;
|
|
300
|
+
if (maxStrings === 1) {
|
|
301
|
+
return {
|
|
302
|
+
phase: "interaction",
|
|
303
|
+
kind: "extended-text",
|
|
304
|
+
cardinality: "single",
|
|
305
|
+
stimulus,
|
|
306
|
+
interaction,
|
|
307
|
+
submitText: function submitText(value) {
|
|
308
|
+
return execute({ kind: "interaction", submission: { type: "extended-text", values: [value] } }, "interaction");
|
|
309
|
+
},
|
|
310
|
+
toJSON: poisonToJSON
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
phase: "interaction",
|
|
315
|
+
kind: "extended-text",
|
|
316
|
+
cardinality: "multiple",
|
|
317
|
+
stimulus,
|
|
318
|
+
interaction,
|
|
319
|
+
maxStrings,
|
|
320
|
+
minStrings,
|
|
321
|
+
submitTexts: function submitTexts(values) {
|
|
322
|
+
const validationError = validateExtendedTextSubmission(values, minStrings, maxStrings);
|
|
323
|
+
if (validationError) {
|
|
324
|
+
return Promise.resolve(errored(validationError, "interaction", {
|
|
325
|
+
kind: "interaction",
|
|
326
|
+
submission: { type: "extended-text", values }
|
|
327
|
+
}));
|
|
328
|
+
}
|
|
329
|
+
return execute({ kind: "interaction", submission: { type: "extended-text", values } }, "interaction");
|
|
330
|
+
},
|
|
331
|
+
toJSON: poisonToJSON
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function pciInteractionState(stimulus, interaction) {
|
|
335
|
+
const { pciId, properties } = interaction;
|
|
336
|
+
function submit(value) {
|
|
337
|
+
log?.debug("pci submit", { pciId });
|
|
338
|
+
const submission = { type: "portable-custom", pciId, value };
|
|
339
|
+
return execute({ kind: "interaction", submission }, "interaction");
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
phase: "interaction",
|
|
343
|
+
kind: "portable-custom",
|
|
344
|
+
stimulus,
|
|
345
|
+
interaction,
|
|
346
|
+
pciId,
|
|
347
|
+
properties,
|
|
348
|
+
submit,
|
|
349
|
+
toJSON: poisonToJSON
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function feedbackState(stimulus, interaction, submission, isCorrect, feedbackContent, correctAnswer) {
|
|
353
|
+
return {
|
|
354
|
+
phase: "feedback",
|
|
355
|
+
stimulus,
|
|
356
|
+
interaction,
|
|
357
|
+
submission,
|
|
358
|
+
isCorrect,
|
|
359
|
+
feedbackContent,
|
|
360
|
+
correctAnswer,
|
|
361
|
+
advance: function advance() {
|
|
362
|
+
return execute({ kind: "observation" }, "observation");
|
|
363
|
+
},
|
|
364
|
+
toJSON: poisonToJSON
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return { execute };
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
async start(studentId) {
|
|
371
|
+
log?.debug("start", { studentId });
|
|
372
|
+
const s = makeSession(studentId);
|
|
373
|
+
return s.execute({ kind: "observation" }, "observation");
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
export {
|
|
378
|
+
create,
|
|
379
|
+
DEFAULT_ORIGIN,
|
|
380
|
+
ADVANCE_PATH
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
//# debugId=B2799CD48726B75C64756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/errors.ts", "../src/client.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import * as errors from \"@superbuilders/errors\"\n\nconst ErrNetwork = errors.new(\"network\")\nconst ErrJsonParse = errors.new(\"json parse\")\nconst ErrUnsupportedPci = errors.new(\"unsupported pci\")\nconst ErrInvalidPublishableKey = errors.new(\"invalid publishable key\")\nconst ErrBadRequest = errors.new(\"bad request\")\nconst ErrServerError = errors.new(\"server error\")\nconst ErrTimeout = errors.new(\"timeout\")\nconst ErrForbidden = errors.new(\"forbidden\")\nconst ErrNotFound = errors.new(\"not found\")\nconst ErrConflict = errors.new(\"conflict\")\nconst ErrRateLimited = errors.new(\"rate limited\")\nconst ErrServiceUnavailable = errors.new(\"service unavailable\")\nconst ErrNotSerializable = errors.new(\n\t\"PrimerState is live in-memory state and must not be serialized or stored\"\n)\nconst ErrInvalidSubmission = errors.new(\"invalid submission\")\nconst ErrMalformedPublishableKey = errors.new(\"malformed publishable key\")\n\nexport {\n\tErrBadRequest,\n\tErrConflict,\n\tErrForbidden,\n\tErrInvalidPublishableKey,\n\tErrInvalidSubmission,\n\tErrMalformedPublishableKey,\n\tErrJsonParse,\n\tErrNetwork,\n\tErrNotFound,\n\tErrNotSerializable,\n\tErrRateLimited,\n\tErrServerError,\n\tErrServiceUnavailable,\n\tErrTimeout,\n\tErrUnsupportedPci\n}\n",
|
|
6
|
+
"import * as errors from \"@superbuilders/errors\"\nimport {\n\tErrBadRequest,\n\tErrConflict,\n\tErrForbidden,\n\tErrInvalidPublishableKey,\n\tErrJsonParse,\n\tErrMalformedPublishableKey,\n\tErrNetwork,\n\tErrNotFound,\n\tErrNotSerializable,\n\tErrRateLimited,\n\tErrServerError,\n\tErrServiceUnavailable,\n\tErrTimeout,\n\tErrUnsupportedPci,\n\tErrInvalidSubmission\n} from \"@superbuilders/primer-tives/errors\"\nimport type { PciId, PciValue } from \"@superbuilders/primer-tives/pci\"\nimport type {\n\tErroredState,\n\tPciInteraction,\n\tPciInteractionState,\n\tPrimerState,\n\tRendererChoice,\n\tRendererCorrectAnswer,\n\tRendererInteraction,\n\tRendererStimulus,\n\tRendererSubmission\n} from \"@superbuilders/primer-tives/types\"\nimport type { ContentInline } from \"@superbuilders/primer-tives/content\"\n\ninterface PrimerLogger {\n\tdebug(message: string, attributes?: Record<string, unknown>): void\n\tinfo(message: string, attributes?: Record<string, unknown>): void\n\twarn(message: string, attributes?: Record<string, unknown>): void\n\terror(message: string, attributes?: Record<string, unknown>): void\n}\n\ntype WireIntent<Pcis extends PciId = PciId> =\n\t| { kind: \"observation\" }\n\t| { kind: \"interaction\"; submission: RendererSubmission<Pcis> }\n\ntype WireResult<Pcis extends PciId = PciId> =\n\t| {\n\t\t\toutcome: \"advanced\"\n\t\t\tstimulus: RendererStimulus | null\n\t\t\tinteraction: RendererInteraction<Pcis> | null\n\t }\n\t| {\n\t\t\toutcome: \"submitted\"\n\t\t\tstimulus: RendererStimulus | null\n\t\t\tinteraction: RendererInteraction<Pcis>\n\t\t\tsubmission: RendererSubmission<Pcis>\n\t\t\tisCorrect: boolean\n\t\t\tfeedbackContent: ContentInline[]\n\t\t\tcorrectAnswer: RendererCorrectAnswer | null\n\t }\n\t| { outcome: \"completed\" }\n\ninterface WireRequestBody<Pcis extends PciId = PciId> {\n\tstudentId: string\n\tsupportedPcis: readonly PciId[]\n\tintent: WireIntent<Pcis>\n}\n\ntype TransportResult<Pcis extends PciId = PciId> =\n\t| { ok: true; data: WireResult<Pcis> }\n\t| { ok: false; error: Error }\n\nconst DEFAULT_ORIGIN = \"https://sb-primer.vercel.app\"\nconst ADVANCE_PATH = \"/api/v0/advance\"\n\ninterface Config<Pcis extends PciId = PciId> {\n\treadonly publishableKey: string\n\treadonly supportedPcis: readonly Pcis[]\n\treadonly origin?: string\n\treadonly fetch?: typeof globalThis.fetch\n\treadonly abort?: AbortController\n\treadonly logger?: PrimerLogger\n}\n\ninterface Client<Pcis extends PciId = PciId> {\n\tstart(studentId: string): Promise<PrimerState<Pcis>>\n}\n\nfunction poisonToJSON(): never {\n\t// biome-ignore lint/plugin: intentional toJSON trap — logging here would spam on every accidental serialize attempt\n\tthrow ErrNotSerializable\n}\n\nfunction httpSentinel(status: number): Error {\n\tif (status === 400) {\n\t\treturn ErrBadRequest\n\t}\n\tif (status === 401) {\n\t\treturn ErrInvalidPublishableKey\n\t}\n\tif (status === 403) {\n\t\treturn ErrForbidden\n\t}\n\tif (status === 404) {\n\t\treturn ErrNotFound\n\t}\n\tif (status === 409) {\n\t\treturn ErrConflict\n\t}\n\tif (status === 422) {\n\t\treturn ErrUnsupportedPci\n\t}\n\tif (status === 429) {\n\t\treturn ErrRateLimited\n\t}\n\tif (status === 502 || status === 503 || status === 504) {\n\t\treturn ErrServiceUnavailable\n\t}\n\treturn ErrServerError\n}\n\nfunction isAbortError(err: unknown): boolean {\n\tif (err instanceof DOMException && err.name === \"AbortError\") {\n\t\treturn true\n\t}\n\tif (err instanceof DOMException && err.name === \"TimeoutError\") {\n\t\treturn true\n\t}\n\treturn false\n}\n\nconst PK_PREFIX = \"pk_\"\n\nfunction create<const Pcis extends PciId>(config: Config<Pcis>): Client<Pcis> {\n\tconst configFetch = config.fetch\n\tconst fetchFn = configFetch ? configFetch : globalThis.fetch\n\tconst log = config.logger\n\n\tif (!config.publishableKey.startsWith(PK_PREFIX)) {\n\t\tlog?.error(\"malformed publishable key\", { prefix: PK_PREFIX })\n\t\t// biome-ignore lint/plugin: client SDK — log is optional config.logger, not slog\n\t\tthrow errors.wrap(ErrMalformedPublishableKey, `key must start with '${PK_PREFIX}'`)\n\t}\n\n\tfunction transportSignal(): AbortSignal | undefined {\n\t\tif (config.abort) {\n\t\t\treturn config.abort.signal\n\t\t}\n\t\treturn undefined\n\t}\n\n\tasync function transport(body: WireRequestBody<Pcis>): Promise<TransportResult<Pcis>> {\n\t\tlog?.debug(\"transport request\", {\n\t\t\tstudentId: body.studentId,\n\t\t\tintentKind: body.intent.kind\n\t\t})\n\n\t\tconst url = config.origin ? `${config.origin}${ADVANCE_PATH}` : ADVANCE_PATH\n\t\tconst fetchResult = await fetchFn(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"X-Primer-Publishable-Key\": config.publishableKey\n\t\t\t},\n\t\t\tbody: JSON.stringify(body),\n\t\t\tsignal: transportSignal()\n\t\t}).then(\n\t\t\tfunction ok(r: Response) {\n\t\t\t\treturn { ok: true, response: r } as const\n\t\t\t},\n\t\t\tfunction fail(err: Error) {\n\t\t\t\treturn { ok: false, error: err } as const\n\t\t\t}\n\t\t)\n\n\t\tif (!fetchResult.ok) {\n\t\t\tif (isAbortError(fetchResult.error)) {\n\t\t\t\tlog?.error(\"transport timeout\", {\n\t\t\t\t\tstudentId: body.studentId,\n\t\t\t\t\tintentKind: body.intent.kind\n\t\t\t\t})\n\t\t\t\treturn { ok: false, error: errors.wrap(ErrTimeout, fetchResult.error.message) }\n\t\t\t}\n\t\t\tlog?.error(\"transport network error\", {\n\t\t\t\tstudentId: body.studentId,\n\t\t\t\terror: fetchResult.error\n\t\t\t})\n\t\t\treturn { ok: false, error: errors.wrap(ErrNetwork, fetchResult.error.message) }\n\t\t}\n\n\t\tconst res = fetchResult.response\n\n\t\tif (!res.ok) {\n\t\t\tconst text = await res.text().catch(function fallback() {\n\t\t\t\treturn \"\"\n\t\t\t})\n\t\t\tconst sentinel = httpSentinel(res.status)\n\t\t\tlog?.error(\"transport http error\", {\n\t\t\t\tstudentId: body.studentId,\n\t\t\t\tstatus: res.status\n\t\t\t})\n\t\t\treturn { ok: false, error: errors.wrap(sentinel, text) }\n\t\t}\n\n\t\tconst jsonResult = await res.json().then(\n\t\t\tfunction ok(data: WireResult<Pcis>) {\n\t\t\t\treturn { ok: true, data } as const\n\t\t\t},\n\t\t\tfunction fail(err: Error) {\n\t\t\t\treturn { ok: false, error: err } as const\n\t\t\t}\n\t\t)\n\n\t\tif (!jsonResult.ok) {\n\t\t\tlog?.error(\"transport json parse failed\", {\n\t\t\t\tstudentId: body.studentId,\n\t\t\t\terror: jsonResult.error\n\t\t\t})\n\t\t\treturn { ok: false, error: errors.wrap(ErrJsonParse, jsonResult.error.message) }\n\t\t}\n\n\t\tlog?.debug(\"transport success\", {\n\t\t\tstudentId: body.studentId,\n\t\t\tintentKind: body.intent.kind\n\t\t})\n\n\t\treturn { ok: true, data: jsonResult.data }\n\t}\n\n\tfunction makeSession(studentId: string) {\n\t\tfunction resolve(result: WireResult<Pcis>): PrimerState<Pcis> {\n\t\t\tswitch (result.outcome) {\n\t\t\t\tcase \"advanced\":\n\t\t\t\t\treturn fromAdvanced(result.stimulus, result.interaction)\n\t\t\t\tcase \"submitted\":\n\t\t\t\t\treturn feedbackState(\n\t\t\t\t\t\tresult.stimulus,\n\t\t\t\t\t\tresult.interaction,\n\t\t\t\t\t\tresult.submission,\n\t\t\t\t\t\tresult.isCorrect,\n\t\t\t\t\t\tresult.feedbackContent,\n\t\t\t\t\t\tresult.correctAnswer\n\t\t\t\t\t)\n\t\t\t\tcase \"completed\":\n\t\t\t\t\treturn { phase: \"completed\", toJSON: poisonToJSON }\n\t\t\t}\n\t\t}\n\n\t\tfunction errored(\n\t\t\terror: Error,\n\t\t\tfailedPhase: \"observation\" | \"interaction\",\n\t\t\tintent: WireIntent<Pcis>\n\t\t): ErroredState<Pcis> {\n\t\t\treturn {\n\t\t\t\tphase: \"errored\",\n\t\t\t\terror,\n\t\t\t\tfailedPhase,\n\t\t\t\tretry: function retry() {\n\t\t\t\t\tlog?.debug(\"retrying from errored state\", { failedPhase })\n\t\t\t\t\treturn execute(intent, failedPhase)\n\t\t\t\t},\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t}\n\t\t}\n\n\t\tasync function execute(\n\t\t\tintent: WireIntent<Pcis>,\n\t\t\tphase: \"observation\" | \"interaction\"\n\t\t): Promise<PrimerState<Pcis>> {\n\t\t\tconst body: WireRequestBody<Pcis> = {\n\t\t\t\tstudentId,\n\t\t\t\tsupportedPcis: config.supportedPcis,\n\t\t\t\tintent\n\t\t\t}\n\n\t\t\tconst result = await transport(body)\n\t\t\tif (!result.ok) {\n\t\t\t\treturn errored(result.error, phase, intent)\n\t\t\t}\n\n\t\t\treturn resolve(result.data)\n\t\t}\n\n\t\tfunction isPciSupported(pciId: string): boolean {\n\t\t\tfor (const id of config.supportedPcis) {\n\t\t\t\tif (id === pciId) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\tfunction fromAdvanced(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: RendererInteraction<Pcis> | null\n\t\t): PrimerState<Pcis> {\n\t\t\tif (interaction === null) {\n\t\t\t\treturn observationState(stimulus)\n\t\t\t}\n\t\t\tif (interaction.type === \"portable-custom\") {\n\t\t\t\tif (!isPciSupported(interaction.pciId)) {\n\t\t\t\t\tlog?.error(\"unsupported pci in frame\", { pciId: interaction.pciId })\n\t\t\t\t\treturn {\n\t\t\t\t\t\tphase: \"fatal\",\n\t\t\t\t\t\terror: errors.wrap(ErrUnsupportedPci, `pci '${interaction.pciId}'`),\n\t\t\t\t\t\ttoJSON: poisonToJSON\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn pendingInteractionState(stimulus, interaction)\n\t\t}\n\n\t\tfunction observationState(stimulus: RendererStimulus | null): PrimerState<Pcis> {\n\t\t\treturn {\n\t\t\t\tphase: \"observation\",\n\t\t\t\tstimulus,\n\t\t\t\tadvance: function advance() {\n\t\t\t\t\treturn execute({ kind: \"observation\" }, \"observation\")\n\t\t\t\t},\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t}\n\t\t}\n\n\t\tfunction pendingInteractionState(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: RendererInteraction<Pcis>\n\t\t): PrimerState<Pcis> {\n\t\t\tswitch (interaction.type) {\n\t\t\t\tcase \"choice\":\n\t\t\t\t\treturn choiceState(\n\t\t\t\t\t\tstimulus,\n\t\t\t\t\t\tinteraction,\n\t\t\t\t\t\tinteraction.options,\n\t\t\t\t\t\tinteraction.maxChoices,\n\t\t\t\t\t\tinteraction.minChoices\n\t\t\t\t\t)\n\t\t\t\tcase \"text-entry\":\n\t\t\t\t\treturn textEntryState(stimulus, interaction)\n\t\t\t\tcase \"extended-text\":\n\t\t\t\t\treturn extendedTextState(stimulus, interaction)\n\t\t\t\tcase \"portable-custom\":\n\t\t\t\t\treturn pciInteractionState(stimulus, interaction)\n\t\t\t}\n\t\t}\n\n\t\tfunction findUnknownKey(selectedKeys: string[], options: RendererChoice[]): string | null {\n\t\t\tconst optionIds = new Set(\n\t\t\t\toptions.map(function getId(o) {\n\t\t\t\t\treturn o.identifier\n\t\t\t\t})\n\t\t\t)\n\t\t\tfor (const key of selectedKeys) {\n\t\t\t\tif (!optionIds.has(key)) {\n\t\t\t\t\treturn key\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\n\t\tfunction validateChoiceSubmission(\n\t\t\tselectedKeys: string[],\n\t\t\toptions: RendererChoice[],\n\t\t\tmaxChoices: number,\n\t\t\tminChoices: number\n\t\t): Error | null {\n\t\t\tif (selectedKeys.length < minChoices) {\n\t\t\t\tlog?.error(\"choice submit below minChoices\", { selectedKeys, minChoices })\n\t\t\t\treturn errors.wrap(ErrInvalidSubmission, `need at least ${minChoices} selections`)\n\t\t\t}\n\t\t\tif (selectedKeys.length > maxChoices) {\n\t\t\t\tlog?.error(\"choice submit above maxChoices\", { selectedKeys, maxChoices })\n\t\t\t\treturn errors.wrap(ErrInvalidSubmission, `at most ${maxChoices} selections`)\n\t\t\t}\n\t\t\tconst uniqueKeys = new Set(selectedKeys)\n\t\t\tif (uniqueKeys.size !== selectedKeys.length) {\n\t\t\t\tlog?.error(\"choice submit has duplicates\", { selectedKeys })\n\t\t\t\treturn errors.wrap(ErrInvalidSubmission, \"duplicate selections\")\n\t\t\t}\n\t\t\tconst unknownKey = findUnknownKey(selectedKeys, options)\n\t\t\tif (unknownKey) {\n\t\t\t\tlog?.error(\"choice submit has unknown key\", { key: unknownKey })\n\t\t\t\treturn errors.wrap(ErrInvalidSubmission, `unknown option '${unknownKey}'`)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\n\t\tfunction choiceState(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: Extract<RendererInteraction<Pcis>, { type: \"choice\" }>,\n\t\t\toptions: RendererChoice[],\n\t\t\tmaxChoices: number,\n\t\t\tminChoices: number\n\t\t): PrimerState<Pcis> {\n\t\t\treturn {\n\t\t\t\tphase: \"interaction\",\n\t\t\t\tkind: \"choice\",\n\t\t\t\tstimulus,\n\t\t\t\tinteraction,\n\t\t\t\toptions,\n\t\t\t\tmaxChoices,\n\t\t\t\tminChoices,\n\t\t\t\tsubmitChoice: function submitChoice(selectedKeys: string[]) {\n\t\t\t\t\tconst validationError = validateChoiceSubmission(\n\t\t\t\t\t\tselectedKeys,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\tmaxChoices,\n\t\t\t\t\t\tminChoices\n\t\t\t\t\t)\n\t\t\t\t\tif (validationError) {\n\t\t\t\t\t\treturn Promise.resolve(\n\t\t\t\t\t\t\terrored(validationError, \"interaction\", {\n\t\t\t\t\t\t\t\tkind: \"interaction\",\n\t\t\t\t\t\t\t\tsubmission: { type: \"choice\", selectedKeys }\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treturn execute(\n\t\t\t\t\t\t{ kind: \"interaction\", submission: { type: \"choice\", selectedKeys } },\n\t\t\t\t\t\t\"interaction\"\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t}\n\t\t}\n\n\t\tfunction textEntryState(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: Extract<RendererInteraction<Pcis>, { type: \"text-entry\" }>\n\t\t): PrimerState<Pcis> {\n\t\t\treturn {\n\t\t\t\tphase: \"interaction\",\n\t\t\t\tkind: \"text-entry\",\n\t\t\t\tstimulus,\n\t\t\t\tinteraction,\n\t\t\t\tsubmitText: function submitText(value: string) {\n\t\t\t\t\treturn execute(\n\t\t\t\t\t\t{ kind: \"interaction\", submission: { type: \"text-entry\", value } },\n\t\t\t\t\t\t\"interaction\"\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t}\n\t\t}\n\n\t\tfunction validateExtendedTextSubmission(\n\t\t\tvalues: string[],\n\t\t\tminStrings: number,\n\t\t\tmaxStrings: number\n\t\t): Error | null {\n\t\t\tif (values.length < minStrings) {\n\t\t\t\tlog?.error(\"extended-text submit below minStrings\", { count: values.length, minStrings })\n\t\t\t\treturn errors.wrap(ErrInvalidSubmission, `need at least ${minStrings} values`)\n\t\t\t}\n\t\t\tif (values.length > maxStrings) {\n\t\t\t\tlog?.error(\"extended-text submit above maxStrings\", { count: values.length, maxStrings })\n\t\t\t\treturn errors.wrap(ErrInvalidSubmission, `at most ${maxStrings} values`)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\n\t\tfunction extendedTextState(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: RendererInteraction<Pcis> & { type: \"extended-text\" }\n\t\t): PrimerState<Pcis> {\n\t\t\tconst maxStrings = interaction.maxStrings\n\t\t\tconst minStrings = interaction.minStrings\n\t\t\tif (maxStrings === 1) {\n\t\t\t\treturn {\n\t\t\t\t\tphase: \"interaction\",\n\t\t\t\t\tkind: \"extended-text\",\n\t\t\t\t\tcardinality: \"single\",\n\t\t\t\t\tstimulus,\n\t\t\t\t\tinteraction,\n\t\t\t\t\tsubmitText: function submitText(value: string) {\n\t\t\t\t\t\treturn execute(\n\t\t\t\t\t\t\t{ kind: \"interaction\", submission: { type: \"extended-text\", values: [value] } },\n\t\t\t\t\t\t\t\"interaction\"\n\t\t\t\t\t\t)\n\t\t\t\t\t},\n\t\t\t\t\ttoJSON: poisonToJSON\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tphase: \"interaction\",\n\t\t\t\tkind: \"extended-text\",\n\t\t\t\tcardinality: \"multiple\",\n\t\t\t\tstimulus,\n\t\t\t\tinteraction,\n\t\t\t\tmaxStrings,\n\t\t\t\tminStrings,\n\t\t\t\tsubmitTexts: function submitTexts(values: string[]) {\n\t\t\t\t\tconst validationError = validateExtendedTextSubmission(values, minStrings, maxStrings)\n\t\t\t\t\tif (validationError) {\n\t\t\t\t\t\treturn Promise.resolve(\n\t\t\t\t\t\t\terrored(validationError, \"interaction\", {\n\t\t\t\t\t\t\t\tkind: \"interaction\",\n\t\t\t\t\t\t\t\tsubmission: { type: \"extended-text\", values }\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\treturn execute(\n\t\t\t\t\t\t{ kind: \"interaction\", submission: { type: \"extended-text\", values } },\n\t\t\t\t\t\t\"interaction\"\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t}\n\t\t}\n\n\t\t// Safe cast: TS cannot verify mapped-union construction from generic Pcis.\n\t\t// The input `interaction: PciInteraction<Pcis>` guarantees pciId↔properties\n\t\t// correlation; destructuring loses TS tracking but runtime is correct.\n\t\tfunction pciInteractionState(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: PciInteraction<Pcis>\n\t\t): PciInteractionState<Pcis> {\n\t\t\tconst { pciId, properties } = interaction\n\t\t\tfunction submit(value: PciValue<typeof pciId>): Promise<PrimerState<Pcis>> {\n\t\t\t\tlog?.debug(\"pci submit\", { pciId })\n\t\t\t\tconst submission = { type: \"portable-custom\" as const, pciId, value }\n\t\t\t\treturn execute({ kind: \"interaction\", submission }, \"interaction\")\n\t\t\t}\n\t\t\t// biome-ignore lint/plugin: TS cannot verify mapped-union construction from generic Pcis — pciId↔properties correlation preserved by input\n\t\t\treturn {\n\t\t\t\tphase: \"interaction\",\n\t\t\t\tkind: \"portable-custom\",\n\t\t\t\tstimulus,\n\t\t\t\tinteraction,\n\t\t\t\tpciId,\n\t\t\t\tproperties,\n\t\t\t\tsubmit,\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t} as PciInteractionState<Pcis>\n\t\t}\n\n\t\tfunction feedbackState(\n\t\t\tstimulus: RendererStimulus | null,\n\t\t\tinteraction: RendererInteraction<Pcis>,\n\t\t\tsubmission: RendererSubmission<Pcis>,\n\t\t\tisCorrect: boolean,\n\t\t\tfeedbackContent: ContentInline[],\n\t\t\tcorrectAnswer: RendererCorrectAnswer | null\n\t\t): PrimerState<Pcis> {\n\t\t\treturn {\n\t\t\t\tphase: \"feedback\",\n\t\t\t\tstimulus,\n\t\t\t\tinteraction,\n\t\t\t\tsubmission,\n\t\t\t\tisCorrect,\n\t\t\t\tfeedbackContent,\n\t\t\t\tcorrectAnswer,\n\t\t\t\tadvance: function advance() {\n\t\t\t\t\treturn execute({ kind: \"observation\" }, \"observation\")\n\t\t\t\t},\n\t\t\t\ttoJSON: poisonToJSON\n\t\t\t}\n\t\t}\n\n\t\treturn { execute }\n\t}\n\n\treturn {\n\t\tasync start(studentId: string): Promise<PrimerState<Pcis>> {\n\t\t\tlog?.debug(\"start\", { studentId })\n\t\t\tconst s = makeSession(studentId)\n\t\t\treturn s.execute({ kind: \"observation\" }, \"observation\")\n\t\t}\n\t}\n}\n\nexport { ADVANCE_PATH, DEFAULT_ORIGIN, create }\nexport type { Client, Config, PrimerLogger }\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "B2799CD48726B75C64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type ContentInline = {
|
|
2
|
+
type: "text";
|
|
3
|
+
value: string;
|
|
4
|
+
} | {
|
|
5
|
+
type: "italic";
|
|
6
|
+
children: ContentInline[];
|
|
7
|
+
};
|
|
8
|
+
type ContentBlock = {
|
|
9
|
+
type: "paragraph";
|
|
10
|
+
children: ContentInline[];
|
|
11
|
+
};
|
|
12
|
+
declare function inlinesToPlainText(nodes: ContentInline[]): string;
|
|
13
|
+
declare function blocksToPlainText(blocks: ContentBlock[]): string;
|
|
14
|
+
export type { ContentBlock, ContentInline };
|
|
15
|
+
export { blocksToPlainText, inlinesToPlainText };
|
|
16
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAA;AAEpG,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAA;AAEpE,iBAAS,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,CAa1D;AAED,iBAAS,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAMzD;AAED,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAA"}
|
package/dist/content.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/content.ts
|
|
2
|
+
function inlinesToPlainText(nodes) {
|
|
3
|
+
const parts = [];
|
|
4
|
+
for (const node of nodes) {
|
|
5
|
+
switch (node.type) {
|
|
6
|
+
case "text":
|
|
7
|
+
parts.push(node.value);
|
|
8
|
+
break;
|
|
9
|
+
case "italic":
|
|
10
|
+
parts.push(inlinesToPlainText(node.children));
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return parts.join("");
|
|
15
|
+
}
|
|
16
|
+
function blocksToPlainText(blocks) {
|
|
17
|
+
return blocks.map(function blockText(block) {
|
|
18
|
+
return inlinesToPlainText(block.children);
|
|
19
|
+
}).join(`
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
inlinesToPlainText,
|
|
24
|
+
blocksToPlainText
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
//# debugId=B2FEC3DAAEEB30A564756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/content.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"type ContentInline = { type: \"text\"; value: string } | { type: \"italic\"; children: ContentInline[] }\n\ntype ContentBlock = { type: \"paragraph\"; children: ContentInline[] }\n\nfunction inlinesToPlainText(nodes: ContentInline[]): string {\n\tconst parts: string[] = []\n\tfor (const node of nodes) {\n\t\tswitch (node.type) {\n\t\t\tcase \"text\":\n\t\t\t\tparts.push(node.value)\n\t\t\t\tbreak\n\t\t\tcase \"italic\":\n\t\t\t\tparts.push(inlinesToPlainText(node.children))\n\t\t\t\tbreak\n\t\t}\n\t}\n\treturn parts.join(\"\")\n}\n\nfunction blocksToPlainText(blocks: ContentBlock[]): string {\n\treturn blocks\n\t\t.map(function blockText(block) {\n\t\t\treturn inlinesToPlainText(block.children)\n\t\t})\n\t\t.join(\"\\n\")\n}\n\nexport type { ContentBlock, ContentInline }\nexport { blocksToPlainText, inlinesToPlainText }\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAIA,SAAS,kBAAkB,CAAC,OAAgC;AAAA,EAC3D,MAAM,QAAkB,CAAC;AAAA,EACzB,WAAW,QAAQ,OAAO;AAAA,IACzB,QAAQ,KAAK;AAAA,WACP;AAAA,QACJ,MAAM,KAAK,KAAK,KAAK;AAAA,QACrB;AAAA,WACI;AAAA,QACJ,MAAM,KAAK,mBAAmB,KAAK,QAAQ,CAAC;AAAA,QAC5C;AAAA;AAAA,EAEH;AAAA,EACA,OAAO,MAAM,KAAK,EAAE;AAAA;AAGrB,SAAS,iBAAiB,CAAC,QAAgC;AAAA,EAC1D,OAAO,OACL,IAAI,SAAS,SAAS,CAAC,OAAO;AAAA,IAC9B,OAAO,mBAAmB,MAAM,QAAQ;AAAA,GACxC,EACA,KAAK;AAAA,CAAI;AAAA;",
|
|
8
|
+
"debugId": "B2FEC3DAAEEB30A564756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const ErrNetwork: Error;
|
|
2
|
+
declare const ErrJsonParse: Error;
|
|
3
|
+
declare const ErrUnsupportedPci: Error;
|
|
4
|
+
declare const ErrInvalidPublishableKey: Error;
|
|
5
|
+
declare const ErrBadRequest: Error;
|
|
6
|
+
declare const ErrServerError: Error;
|
|
7
|
+
declare const ErrTimeout: Error;
|
|
8
|
+
declare const ErrForbidden: Error;
|
|
9
|
+
declare const ErrNotFound: Error;
|
|
10
|
+
declare const ErrConflict: Error;
|
|
11
|
+
declare const ErrRateLimited: Error;
|
|
12
|
+
declare const ErrServiceUnavailable: Error;
|
|
13
|
+
declare const ErrNotSerializable: Error;
|
|
14
|
+
declare const ErrInvalidSubmission: Error;
|
|
15
|
+
declare const ErrMalformedPublishableKey: Error;
|
|
16
|
+
export { ErrBadRequest, ErrConflict, ErrForbidden, ErrInvalidPublishableKey, ErrInvalidSubmission, ErrMalformedPublishableKey, ErrJsonParse, ErrNetwork, ErrNotFound, ErrNotSerializable, ErrRateLimited, ErrServerError, ErrServiceUnavailable, ErrTimeout, ErrUnsupportedPci };
|
|
17
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,UAAU,OAAwB,CAAA;AACxC,QAAA,MAAM,YAAY,OAA2B,CAAA;AAC7C,QAAA,MAAM,iBAAiB,OAAgC,CAAA;AACvD,QAAA,MAAM,wBAAwB,OAAwC,CAAA;AACtE,QAAA,MAAM,aAAa,OAA4B,CAAA;AAC/C,QAAA,MAAM,cAAc,OAA6B,CAAA;AACjD,QAAA,MAAM,UAAU,OAAwB,CAAA;AACxC,QAAA,MAAM,YAAY,OAA0B,CAAA;AAC5C,QAAA,MAAM,WAAW,OAA0B,CAAA;AAC3C,QAAA,MAAM,WAAW,OAAyB,CAAA;AAC1C,QAAA,MAAM,cAAc,OAA6B,CAAA;AACjD,QAAA,MAAM,qBAAqB,OAAoC,CAAA;AAC/D,QAAA,MAAM,kBAAkB,OAEvB,CAAA;AACD,QAAA,MAAM,oBAAoB,OAAmC,CAAA;AAC7D,QAAA,MAAM,0BAA0B,OAA0C,CAAA;AAE1E,OAAO,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,YAAY,EACZ,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,CAAA"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
import * as errors from "@superbuilders/errors";
|
|
3
|
+
var ErrNetwork = errors.new("network");
|
|
4
|
+
var ErrJsonParse = errors.new("json parse");
|
|
5
|
+
var ErrUnsupportedPci = errors.new("unsupported pci");
|
|
6
|
+
var ErrInvalidPublishableKey = errors.new("invalid publishable key");
|
|
7
|
+
var ErrBadRequest = errors.new("bad request");
|
|
8
|
+
var ErrServerError = errors.new("server error");
|
|
9
|
+
var ErrTimeout = errors.new("timeout");
|
|
10
|
+
var ErrForbidden = errors.new("forbidden");
|
|
11
|
+
var ErrNotFound = errors.new("not found");
|
|
12
|
+
var ErrConflict = errors.new("conflict");
|
|
13
|
+
var ErrRateLimited = errors.new("rate limited");
|
|
14
|
+
var ErrServiceUnavailable = errors.new("service unavailable");
|
|
15
|
+
var ErrNotSerializable = errors.new("PrimerState is live in-memory state and must not be serialized or stored");
|
|
16
|
+
var ErrInvalidSubmission = errors.new("invalid submission");
|
|
17
|
+
var ErrMalformedPublishableKey = errors.new("malformed publishable key");
|
|
18
|
+
export {
|
|
19
|
+
ErrUnsupportedPci,
|
|
20
|
+
ErrTimeout,
|
|
21
|
+
ErrServiceUnavailable,
|
|
22
|
+
ErrServerError,
|
|
23
|
+
ErrRateLimited,
|
|
24
|
+
ErrNotSerializable,
|
|
25
|
+
ErrNotFound,
|
|
26
|
+
ErrNetwork,
|
|
27
|
+
ErrMalformedPublishableKey,
|
|
28
|
+
ErrJsonParse,
|
|
29
|
+
ErrInvalidSubmission,
|
|
30
|
+
ErrInvalidPublishableKey,
|
|
31
|
+
ErrForbidden,
|
|
32
|
+
ErrConflict,
|
|
33
|
+
ErrBadRequest
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
//# debugId=DC88F476D6E45CE664756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/errors.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import * as errors from \"@superbuilders/errors\"\n\nconst ErrNetwork = errors.new(\"network\")\nconst ErrJsonParse = errors.new(\"json parse\")\nconst ErrUnsupportedPci = errors.new(\"unsupported pci\")\nconst ErrInvalidPublishableKey = errors.new(\"invalid publishable key\")\nconst ErrBadRequest = errors.new(\"bad request\")\nconst ErrServerError = errors.new(\"server error\")\nconst ErrTimeout = errors.new(\"timeout\")\nconst ErrForbidden = errors.new(\"forbidden\")\nconst ErrNotFound = errors.new(\"not found\")\nconst ErrConflict = errors.new(\"conflict\")\nconst ErrRateLimited = errors.new(\"rate limited\")\nconst ErrServiceUnavailable = errors.new(\"service unavailable\")\nconst ErrNotSerializable = errors.new(\n\t\"PrimerState is live in-memory state and must not be serialized or stored\"\n)\nconst ErrInvalidSubmission = errors.new(\"invalid submission\")\nconst ErrMalformedPublishableKey = errors.new(\"malformed publishable key\")\n\nexport {\n\tErrBadRequest,\n\tErrConflict,\n\tErrForbidden,\n\tErrInvalidPublishableKey,\n\tErrInvalidSubmission,\n\tErrMalformedPublishableKey,\n\tErrJsonParse,\n\tErrNetwork,\n\tErrNotFound,\n\tErrNotSerializable,\n\tErrRateLimited,\n\tErrServerError,\n\tErrServiceUnavailable,\n\tErrTimeout,\n\tErrUnsupportedPci\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAA;AAEA,IAAM,aAAoB,WAAI,SAAS;AACvC,IAAM,eAAsB,WAAI,YAAY;AAC5C,IAAM,oBAA2B,WAAI,iBAAiB;AACtD,IAAM,2BAAkC,WAAI,yBAAyB;AACrE,IAAM,gBAAuB,WAAI,aAAa;AAC9C,IAAM,iBAAwB,WAAI,cAAc;AAChD,IAAM,aAAoB,WAAI,SAAS;AACvC,IAAM,eAAsB,WAAI,WAAW;AAC3C,IAAM,cAAqB,WAAI,WAAW;AAC1C,IAAM,cAAqB,WAAI,UAAU;AACzC,IAAM,iBAAwB,WAAI,cAAc;AAChD,IAAM,wBAA+B,WAAI,qBAAqB;AAC9D,IAAM,qBAA4B,WACjC,0EACD;AACA,IAAM,uBAA8B,WAAI,oBAAoB;AAC5D,IAAM,6BAAoC,WAAI,2BAA2B;",
|
|
8
|
+
"debugId": "DC88F476D6E45CE664756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/pci.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
interface DivisionRemainderProps {
|
|
2
|
+
dividend: number;
|
|
3
|
+
divisor: number;
|
|
4
|
+
}
|
|
5
|
+
interface DivisionRemainderSubmission {
|
|
6
|
+
quotient: string;
|
|
7
|
+
remainder: string;
|
|
8
|
+
}
|
|
9
|
+
interface FractionAdditionProps {
|
|
10
|
+
left: {
|
|
11
|
+
numerator: number;
|
|
12
|
+
denominator: number;
|
|
13
|
+
};
|
|
14
|
+
right: {
|
|
15
|
+
numerator: number;
|
|
16
|
+
denominator: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
interface FractionAdditionSubmission {
|
|
20
|
+
numerator: string;
|
|
21
|
+
denominator: string;
|
|
22
|
+
}
|
|
23
|
+
type PciUrn = `urn:primer:pci:${string}`;
|
|
24
|
+
interface PciRegistry {
|
|
25
|
+
"urn:primer:pci:division-remainder": {
|
|
26
|
+
props: DivisionRemainderProps;
|
|
27
|
+
value: DivisionRemainderSubmission;
|
|
28
|
+
};
|
|
29
|
+
"urn:primer:pci:fraction-addition": {
|
|
30
|
+
props: FractionAdditionProps;
|
|
31
|
+
value: FractionAdditionSubmission;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
type PciId = keyof PciRegistry & string;
|
|
35
|
+
type PciProps<K extends PciId> = PciRegistry[K]["props"];
|
|
36
|
+
type PciValue<K extends PciId> = PciRegistry[K]["value"];
|
|
37
|
+
export type { DivisionRemainderProps, DivisionRemainderSubmission, FractionAdditionProps, FractionAdditionSubmission, PciId, PciProps, PciRegistry, PciUrn, PciValue };
|
|
38
|
+
//# sourceMappingURL=pci.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pci.d.ts","sourceRoot":"","sources":["../src/pci.ts"],"names":[],"mappings":"AAAA,UAAU,sBAAsB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CACf;AAED,UAAU,2BAA2B;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,qBAAqB;IAC9B,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CACjD;AAED,UAAU,0BAA0B;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,MAAM,GAAG,kBAAkB,MAAM,EAAE,CAAA;AAExC,UAAU,WAAW;IACpB,mCAAmC,EAAE;QACpC,KAAK,EAAE,sBAAsB,CAAA;QAC7B,KAAK,EAAE,2BAA2B,CAAA;KAClC,CAAA;IACD,kCAAkC,EAAE;QACnC,KAAK,EAAE,qBAAqB,CAAA;QAC5B,KAAK,EAAE,0BAA0B,CAAA;KACjC,CAAA;CACD;AAMD,KAAK,KAAK,GAAG,MAAM,WAAW,GAAG,MAAM,CAAA;AACvC,KAAK,QAAQ,CAAC,CAAC,SAAS,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AACxD,KAAK,QAAQ,CAAC,CAAC,SAAS,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AAExD,YAAY,EACX,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,EACL,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAQ,EACR,CAAA"}
|
package/dist/pci.js
ADDED
package/dist/pci.js.map
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { ContentBlock, ContentInline } from "./content";
|
|
2
|
+
import type { PciId, PciProps, PciValue } from "./pci";
|
|
3
|
+
type RendererCorrectScalarValue = {
|
|
4
|
+
kind: "identifier";
|
|
5
|
+
value: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "string";
|
|
8
|
+
value: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: "integer";
|
|
11
|
+
value: number;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "float";
|
|
14
|
+
value: number;
|
|
15
|
+
};
|
|
16
|
+
type RendererCorrectAnswer = {
|
|
17
|
+
kind: "single";
|
|
18
|
+
value: RendererCorrectScalarValue | null;
|
|
19
|
+
} | {
|
|
20
|
+
kind: "multiple";
|
|
21
|
+
values: RendererCorrectScalarValue[];
|
|
22
|
+
} | {
|
|
23
|
+
kind: "record";
|
|
24
|
+
fields: Array<{
|
|
25
|
+
fieldIdentifier: string;
|
|
26
|
+
baseType: "identifier" | "string" | "integer" | "float";
|
|
27
|
+
value: RendererCorrectScalarValue | null;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
interface NonSerializable {
|
|
31
|
+
toJSON(): never;
|
|
32
|
+
}
|
|
33
|
+
interface BodyStimulus {
|
|
34
|
+
type: "body";
|
|
35
|
+
body: ContentBlock[];
|
|
36
|
+
}
|
|
37
|
+
interface ImageStimulus {
|
|
38
|
+
type: "image";
|
|
39
|
+
description: ContentInline[];
|
|
40
|
+
src: string;
|
|
41
|
+
}
|
|
42
|
+
type RendererStimulus = BodyStimulus | ImageStimulus;
|
|
43
|
+
interface RendererChoice {
|
|
44
|
+
identifier: string;
|
|
45
|
+
content: ContentInline[];
|
|
46
|
+
}
|
|
47
|
+
type PciInteraction<Pcis extends PciId = PciId> = {
|
|
48
|
+
[K in Pcis]: {
|
|
49
|
+
type: "portable-custom";
|
|
50
|
+
prompt: ContentInline[];
|
|
51
|
+
pciId: K;
|
|
52
|
+
properties: PciProps<K>;
|
|
53
|
+
};
|
|
54
|
+
}[Pcis];
|
|
55
|
+
type RendererInteraction<Pcis extends PciId = PciId> = {
|
|
56
|
+
type: "choice";
|
|
57
|
+
prompt: ContentInline[];
|
|
58
|
+
options: RendererChoice[];
|
|
59
|
+
shuffle: boolean;
|
|
60
|
+
maxChoices: number;
|
|
61
|
+
minChoices: number;
|
|
62
|
+
} | {
|
|
63
|
+
type: "text-entry";
|
|
64
|
+
prompt: ContentInline[];
|
|
65
|
+
base: 10;
|
|
66
|
+
expectedLength?: number;
|
|
67
|
+
patternMask?: string;
|
|
68
|
+
placeholderText?: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "extended-text";
|
|
71
|
+
prompt: ContentInline[];
|
|
72
|
+
format: "plain";
|
|
73
|
+
expectedLines?: number;
|
|
74
|
+
expectedLength?: number;
|
|
75
|
+
patternMask?: string;
|
|
76
|
+
placeholderText?: string;
|
|
77
|
+
maxStrings: number;
|
|
78
|
+
minStrings: number;
|
|
79
|
+
} | PciInteraction<Pcis>;
|
|
80
|
+
type PciSubmission<Pcis extends PciId = PciId> = {
|
|
81
|
+
[K in Pcis]: {
|
|
82
|
+
type: "portable-custom";
|
|
83
|
+
pciId: K;
|
|
84
|
+
value: PciValue<K>;
|
|
85
|
+
};
|
|
86
|
+
}[Pcis];
|
|
87
|
+
type RendererSubmission<Pcis extends PciId = PciId> = {
|
|
88
|
+
type: "choice";
|
|
89
|
+
selectedKeys: string[];
|
|
90
|
+
} | {
|
|
91
|
+
type: "text-entry";
|
|
92
|
+
value: string;
|
|
93
|
+
} | {
|
|
94
|
+
type: "extended-text";
|
|
95
|
+
values: string[];
|
|
96
|
+
} | PciSubmission<Pcis>;
|
|
97
|
+
interface ObservationState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
98
|
+
readonly phase: "observation";
|
|
99
|
+
readonly stimulus: RendererStimulus | null;
|
|
100
|
+
advance(): Promise<PrimerState<Pcis>>;
|
|
101
|
+
}
|
|
102
|
+
interface ChoiceState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
103
|
+
readonly phase: "interaction";
|
|
104
|
+
readonly kind: "choice";
|
|
105
|
+
readonly stimulus: RendererStimulus | null;
|
|
106
|
+
readonly interaction: Extract<RendererInteraction<Pcis>, {
|
|
107
|
+
type: "choice";
|
|
108
|
+
}>;
|
|
109
|
+
readonly options: RendererChoice[];
|
|
110
|
+
readonly maxChoices: number;
|
|
111
|
+
readonly minChoices: number;
|
|
112
|
+
submitChoice(selectedKeys: string[]): Promise<PrimerState<Pcis>>;
|
|
113
|
+
}
|
|
114
|
+
interface TextEntryState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
115
|
+
readonly phase: "interaction";
|
|
116
|
+
readonly kind: "text-entry";
|
|
117
|
+
readonly stimulus: RendererStimulus | null;
|
|
118
|
+
readonly interaction: Extract<RendererInteraction<Pcis>, {
|
|
119
|
+
type: "text-entry";
|
|
120
|
+
}>;
|
|
121
|
+
submitText(value: string): Promise<PrimerState<Pcis>>;
|
|
122
|
+
}
|
|
123
|
+
interface ExtendedTextSingleState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
124
|
+
readonly phase: "interaction";
|
|
125
|
+
readonly kind: "extended-text";
|
|
126
|
+
readonly cardinality: "single";
|
|
127
|
+
readonly stimulus: RendererStimulus | null;
|
|
128
|
+
readonly interaction: Extract<RendererInteraction<Pcis>, {
|
|
129
|
+
type: "extended-text";
|
|
130
|
+
}>;
|
|
131
|
+
submitText(value: string): Promise<PrimerState<Pcis>>;
|
|
132
|
+
}
|
|
133
|
+
interface ExtendedTextMultipleState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
134
|
+
readonly phase: "interaction";
|
|
135
|
+
readonly kind: "extended-text";
|
|
136
|
+
readonly cardinality: "multiple";
|
|
137
|
+
readonly stimulus: RendererStimulus | null;
|
|
138
|
+
readonly interaction: Extract<RendererInteraction<Pcis>, {
|
|
139
|
+
type: "extended-text";
|
|
140
|
+
}>;
|
|
141
|
+
readonly maxStrings: number;
|
|
142
|
+
readonly minStrings: number;
|
|
143
|
+
submitTexts(values: string[]): Promise<PrimerState<Pcis>>;
|
|
144
|
+
}
|
|
145
|
+
type ExtendedTextState<Pcis extends PciId = PciId> = ExtendedTextSingleState<Pcis> | ExtendedTextMultipleState<Pcis>;
|
|
146
|
+
type PciInteractionState<Pcis extends PciId = PciId> = {
|
|
147
|
+
[K in Pcis]: NonSerializable & {
|
|
148
|
+
readonly phase: "interaction";
|
|
149
|
+
readonly kind: "portable-custom";
|
|
150
|
+
readonly stimulus: RendererStimulus | null;
|
|
151
|
+
readonly interaction: PciInteraction<K>;
|
|
152
|
+
readonly pciId: K;
|
|
153
|
+
readonly properties: PciProps<K>;
|
|
154
|
+
submit(value: PciValue<K>): Promise<PrimerState<Pcis>>;
|
|
155
|
+
};
|
|
156
|
+
}[Pcis];
|
|
157
|
+
type InteractionState<Pcis extends PciId = PciId> = ChoiceState<Pcis> | TextEntryState<Pcis> | ExtendedTextState<Pcis> | PciInteractionState<Pcis>;
|
|
158
|
+
interface FeedbackState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
159
|
+
readonly phase: "feedback";
|
|
160
|
+
readonly stimulus: RendererStimulus | null;
|
|
161
|
+
readonly interaction: RendererInteraction<Pcis>;
|
|
162
|
+
readonly submission: RendererSubmission<Pcis>;
|
|
163
|
+
readonly isCorrect: boolean;
|
|
164
|
+
readonly feedbackContent: ContentInline[];
|
|
165
|
+
readonly correctAnswer: RendererCorrectAnswer | null;
|
|
166
|
+
advance(): Promise<PrimerState<Pcis>>;
|
|
167
|
+
}
|
|
168
|
+
interface CompletedState extends NonSerializable {
|
|
169
|
+
readonly phase: "completed";
|
|
170
|
+
}
|
|
171
|
+
interface ErroredState<Pcis extends PciId = PciId> extends NonSerializable {
|
|
172
|
+
readonly phase: "errored";
|
|
173
|
+
readonly error: Error;
|
|
174
|
+
readonly failedPhase: "observation" | "interaction";
|
|
175
|
+
retry(): Promise<PrimerState<Pcis>>;
|
|
176
|
+
}
|
|
177
|
+
interface FatalState extends NonSerializable {
|
|
178
|
+
readonly phase: "fatal";
|
|
179
|
+
readonly error: Error;
|
|
180
|
+
}
|
|
181
|
+
type PrimerState<Pcis extends PciId = PciId> = ObservationState<Pcis> | InteractionState<Pcis> | FeedbackState<Pcis> | CompletedState | ErroredState<Pcis> | FatalState;
|
|
182
|
+
interface PciRenderProps<K extends PciId> {
|
|
183
|
+
properties: PciProps<K>;
|
|
184
|
+
submitted: boolean;
|
|
185
|
+
onValueChange: (value: PciValue<K> | null) => void;
|
|
186
|
+
}
|
|
187
|
+
export type { BodyStimulus, ChoiceState, CompletedState, ErroredState, ExtendedTextMultipleState, ExtendedTextSingleState, ExtendedTextState, FatalState, FeedbackState, ImageStimulus, InteractionState, NonSerializable, ObservationState, PciInteraction, PciInteractionState, PciRenderProps, PciSubmission, PrimerState, RendererChoice, RendererCorrectAnswer, RendererCorrectScalarValue, RendererInteraction, RendererStimulus, RendererSubmission, TextEntryState };
|
|
188
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@superbuilders/primer-tives",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
"./client": {
|
|
7
|
+
"types": "./dist/client.d.ts",
|
|
8
|
+
"import": "./dist/client.js"
|
|
9
|
+
},
|
|
10
|
+
"./types": {
|
|
11
|
+
"types": "./dist/types.d.ts",
|
|
12
|
+
"import": "./dist/types.js"
|
|
13
|
+
},
|
|
14
|
+
"./content": {
|
|
15
|
+
"types": "./dist/content.d.ts",
|
|
16
|
+
"import": "./dist/content.js"
|
|
17
|
+
},
|
|
18
|
+
"./errors": {
|
|
19
|
+
"types": "./dist/errors.d.ts",
|
|
20
|
+
"import": "./dist/errors.js"
|
|
21
|
+
},
|
|
22
|
+
"./pci": {
|
|
23
|
+
"types": "./dist/pci.d.ts",
|
|
24
|
+
"import": "./dist/pci.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@superbuilders/errors": "^3.0.2"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "bun run build.ts",
|
|
35
|
+
"typecheck": "bun --bun tsc --noEmit"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"resolve-tspaths": "^0.8.23"
|
|
39
|
+
}
|
|
40
|
+
}
|