@superbuilders/primer-tives 0.0.3 → 0.0.5
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 +68 -55
- package/dist/choice-state.d.ts +8 -0
- package/dist/choice-state.d.ts.map +1 -0
- package/dist/client.d.ts +2 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/consumed.d.ts +3 -0
- package/dist/consumed.d.ts.map +1 -0
- package/dist/extended-text-state.d.ts +8 -0
- package/dist/extended-text-state.d.ts.map +1 -0
- package/dist/feedback-state.d.ts +7 -0
- package/dist/feedback-state.d.ts.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +571 -0
- package/dist/index.js.map +21 -0
- package/dist/observation-state.d.ts +6 -0
- package/dist/observation-state.d.ts.map +1 -0
- package/dist/pci-state.d.ts +6 -0
- package/dist/pci-state.d.ts.map +1 -0
- package/dist/session-context.d.ts +24 -0
- package/dist/session-context.d.ts.map +1 -0
- package/dist/session.d.ts +16 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/text-entry-state.d.ts +8 -0
- package/dist/text-entry-state.d.ts.map +1 -0
- package/dist/transport.d.ts +46 -0
- package/dist/transport.d.ts.map +1 -0
- package/package.json +4 -20
- package/dist/client.js +0 -400
- package/dist/client.js.map +0 -11
- package/dist/content.js +0 -27
- package/dist/content.js.map +0 -10
- package/dist/errors.js +0 -36
- package/dist/errors.js.map +0 -10
- package/dist/pci.js +0 -2
- package/dist/pci.js.map +0 -9
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -9
package/dist/index.js
ADDED
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import * as errors6 from "@superbuilders/errors";
|
|
3
|
+
|
|
4
|
+
// src/errors.ts
|
|
5
|
+
import * as errors from "@superbuilders/errors";
|
|
6
|
+
var ErrNetwork = errors.new("network");
|
|
7
|
+
var ErrJsonParse = errors.new("json parse");
|
|
8
|
+
var ErrUnsupportedPci = errors.new("unsupported pci");
|
|
9
|
+
var ErrInvalidPublishableKey = errors.new("invalid publishable key");
|
|
10
|
+
var ErrBadRequest = errors.new("bad request");
|
|
11
|
+
var ErrServerError = errors.new("server error");
|
|
12
|
+
var ErrTimeout = errors.new("timeout");
|
|
13
|
+
var ErrForbidden = errors.new("forbidden");
|
|
14
|
+
var ErrNotFound = errors.new("not found");
|
|
15
|
+
var ErrConflict = errors.new("conflict");
|
|
16
|
+
var ErrRateLimited = errors.new("rate limited");
|
|
17
|
+
var ErrServiceUnavailable = errors.new("service unavailable");
|
|
18
|
+
var ErrNotSerializable = errors.new("PrimerState is live in-memory state and must not be serialized or stored");
|
|
19
|
+
var ErrInvalidSubmission = errors.new("invalid submission");
|
|
20
|
+
var ErrMalformedPublishableKey = errors.new("malformed publishable key");
|
|
21
|
+
|
|
22
|
+
// src/transport.ts
|
|
23
|
+
import * as errors2 from "@superbuilders/errors";
|
|
24
|
+
var ADVANCE_PATH = "/api/v0/advance";
|
|
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
|
+
function createTransport(tc) {
|
|
62
|
+
const fetchFn = tc.fetch ? tc.fetch : globalThis.fetch;
|
|
63
|
+
const log = tc.log;
|
|
64
|
+
function transportSignal() {
|
|
65
|
+
if (tc.abort) {
|
|
66
|
+
return tc.abort.signal;
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
async function transport(body) {
|
|
71
|
+
log?.debug("transport request", {
|
|
72
|
+
studentId: body.studentId,
|
|
73
|
+
intentKind: body.intent.kind
|
|
74
|
+
});
|
|
75
|
+
const url = tc.origin ? `${tc.origin}${ADVANCE_PATH}` : ADVANCE_PATH;
|
|
76
|
+
const fetchResult = await fetchFn(url, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": "application/json",
|
|
80
|
+
"X-Primer-Publishable-Key": tc.publishableKey
|
|
81
|
+
},
|
|
82
|
+
body: JSON.stringify(body),
|
|
83
|
+
signal: transportSignal()
|
|
84
|
+
}).then(function ok(r) {
|
|
85
|
+
return { ok: true, response: r };
|
|
86
|
+
}, function fail(err) {
|
|
87
|
+
return { ok: false, error: err };
|
|
88
|
+
});
|
|
89
|
+
if (!fetchResult.ok) {
|
|
90
|
+
if (isAbortError(fetchResult.error)) {
|
|
91
|
+
log?.error("transport timeout", {
|
|
92
|
+
studentId: body.studentId,
|
|
93
|
+
intentKind: body.intent.kind
|
|
94
|
+
});
|
|
95
|
+
return { ok: false, error: errors2.wrap(ErrTimeout, fetchResult.error.message) };
|
|
96
|
+
}
|
|
97
|
+
log?.error("transport network error", {
|
|
98
|
+
studentId: body.studentId,
|
|
99
|
+
error: fetchResult.error
|
|
100
|
+
});
|
|
101
|
+
return { ok: false, error: errors2.wrap(ErrNetwork, fetchResult.error.message) };
|
|
102
|
+
}
|
|
103
|
+
const res = fetchResult.response;
|
|
104
|
+
if (!res.ok) {
|
|
105
|
+
const text = await res.text().catch(function fallback() {
|
|
106
|
+
return "";
|
|
107
|
+
});
|
|
108
|
+
const sentinel = httpSentinel(res.status);
|
|
109
|
+
log?.error("transport http error", {
|
|
110
|
+
studentId: body.studentId,
|
|
111
|
+
status: res.status
|
|
112
|
+
});
|
|
113
|
+
return { ok: false, error: errors2.wrap(sentinel, text) };
|
|
114
|
+
}
|
|
115
|
+
const jsonResult = await res.json().then(function ok(data) {
|
|
116
|
+
return { ok: true, data };
|
|
117
|
+
}, function fail(err) {
|
|
118
|
+
return { ok: false, error: err };
|
|
119
|
+
});
|
|
120
|
+
if (!jsonResult.ok) {
|
|
121
|
+
log?.error("transport json parse failed", {
|
|
122
|
+
studentId: body.studentId,
|
|
123
|
+
error: jsonResult.error
|
|
124
|
+
});
|
|
125
|
+
return { ok: false, error: errors2.wrap(ErrJsonParse, jsonResult.error.message) };
|
|
126
|
+
}
|
|
127
|
+
log?.debug("transport success", {
|
|
128
|
+
studentId: body.studentId,
|
|
129
|
+
intentKind: body.intent.kind
|
|
130
|
+
});
|
|
131
|
+
return { ok: true, data: jsonResult.data };
|
|
132
|
+
}
|
|
133
|
+
return transport;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/session.ts
|
|
137
|
+
import * as errors5 from "@superbuilders/errors";
|
|
138
|
+
|
|
139
|
+
// src/consumed.ts
|
|
140
|
+
function poisonToJSON() {
|
|
141
|
+
throw ErrNotSerializable;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/choice-state.ts
|
|
145
|
+
import * as errors3 from "@superbuilders/errors";
|
|
146
|
+
function findUnknownKey(selectedKeys, options) {
|
|
147
|
+
const optionIds = new Set(options.map(function getId(o) {
|
|
148
|
+
return o.identifier;
|
|
149
|
+
}));
|
|
150
|
+
for (const key of selectedKeys) {
|
|
151
|
+
if (!optionIds.has(key)) {
|
|
152
|
+
return key;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
function validateChoiceSubmission(log, selectedKeys, options, maxChoices, minChoices) {
|
|
158
|
+
if (selectedKeys.length < minChoices) {
|
|
159
|
+
log?.error("choice submit below minChoices", { selectedKeys, minChoices });
|
|
160
|
+
return errors3.wrap(ErrInvalidSubmission, `need at least ${minChoices} selections`);
|
|
161
|
+
}
|
|
162
|
+
if (selectedKeys.length > maxChoices) {
|
|
163
|
+
log?.error("choice submit above maxChoices", { selectedKeys, maxChoices });
|
|
164
|
+
return errors3.wrap(ErrInvalidSubmission, `at most ${maxChoices} selections`);
|
|
165
|
+
}
|
|
166
|
+
const uniqueKeys = new Set(selectedKeys);
|
|
167
|
+
if (uniqueKeys.size !== selectedKeys.length) {
|
|
168
|
+
log?.error("choice submit has duplicates", { selectedKeys });
|
|
169
|
+
return errors3.wrap(ErrInvalidSubmission, "duplicate selections");
|
|
170
|
+
}
|
|
171
|
+
const unknownKey = findUnknownKey(selectedKeys, options);
|
|
172
|
+
if (unknownKey) {
|
|
173
|
+
log?.error("choice submit has unknown key", { key: unknownKey });
|
|
174
|
+
return errors3.wrap(ErrInvalidSubmission, `unknown option '${unknownKey}'`);
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
function choiceState(ctx, stimulus, interaction, options, maxChoices, minChoices) {
|
|
179
|
+
let pending;
|
|
180
|
+
return {
|
|
181
|
+
phase: "interaction",
|
|
182
|
+
kind: "choice",
|
|
183
|
+
stimulus,
|
|
184
|
+
interaction,
|
|
185
|
+
options,
|
|
186
|
+
maxChoices,
|
|
187
|
+
minChoices,
|
|
188
|
+
submitChoice: function submitChoice(selectedKeys) {
|
|
189
|
+
if (pending) {
|
|
190
|
+
return pending;
|
|
191
|
+
}
|
|
192
|
+
const validationError = validateChoiceSubmission(ctx.log, selectedKeys, options, maxChoices, minChoices);
|
|
193
|
+
if (validationError) {
|
|
194
|
+
return Promise.resolve(ctx.errored(validationError, "interaction", {
|
|
195
|
+
kind: "interaction",
|
|
196
|
+
submission: { type: "choice", selectedKeys }
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
pending = ctx.execute({ kind: "interaction", submission: { type: "choice", selectedKeys } }, "interaction");
|
|
200
|
+
return pending;
|
|
201
|
+
},
|
|
202
|
+
timeout: function timeout() {
|
|
203
|
+
if (pending) {
|
|
204
|
+
return pending;
|
|
205
|
+
}
|
|
206
|
+
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
207
|
+
return pending;
|
|
208
|
+
},
|
|
209
|
+
toJSON: poisonToJSON
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/extended-text-state.ts
|
|
214
|
+
import * as errors4 from "@superbuilders/errors";
|
|
215
|
+
function validateExtendedTextSubmission(log, values, minStrings, maxStrings) {
|
|
216
|
+
if (values.length < minStrings) {
|
|
217
|
+
log?.error("extended-text submit below minStrings", { count: values.length, minStrings });
|
|
218
|
+
return errors4.wrap(ErrInvalidSubmission, `need at least ${minStrings} values`);
|
|
219
|
+
}
|
|
220
|
+
if (values.length > maxStrings) {
|
|
221
|
+
log?.error("extended-text submit above maxStrings", { count: values.length, maxStrings });
|
|
222
|
+
return errors4.wrap(ErrInvalidSubmission, `at most ${maxStrings} values`);
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
function extendedTextState(ctx, stimulus, interaction) {
|
|
227
|
+
const maxStrings = interaction.maxStrings;
|
|
228
|
+
const minStrings = interaction.minStrings;
|
|
229
|
+
if (maxStrings === 1) {
|
|
230
|
+
let pending2;
|
|
231
|
+
return {
|
|
232
|
+
phase: "interaction",
|
|
233
|
+
kind: "extended-text",
|
|
234
|
+
cardinality: "single",
|
|
235
|
+
stimulus,
|
|
236
|
+
interaction,
|
|
237
|
+
submitText: function submitText(value) {
|
|
238
|
+
if (pending2) {
|
|
239
|
+
return pending2;
|
|
240
|
+
}
|
|
241
|
+
pending2 = ctx.execute({ kind: "interaction", submission: { type: "extended-text", values: [value] } }, "interaction");
|
|
242
|
+
return pending2;
|
|
243
|
+
},
|
|
244
|
+
timeout: function timeout() {
|
|
245
|
+
if (pending2) {
|
|
246
|
+
return pending2;
|
|
247
|
+
}
|
|
248
|
+
pending2 = ctx.execute({ kind: "timeout" }, "timeout");
|
|
249
|
+
return pending2;
|
|
250
|
+
},
|
|
251
|
+
toJSON: poisonToJSON
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
let pending;
|
|
255
|
+
return {
|
|
256
|
+
phase: "interaction",
|
|
257
|
+
kind: "extended-text",
|
|
258
|
+
cardinality: "multiple",
|
|
259
|
+
stimulus,
|
|
260
|
+
interaction,
|
|
261
|
+
maxStrings,
|
|
262
|
+
minStrings,
|
|
263
|
+
submitTexts: function submitTexts(values) {
|
|
264
|
+
if (pending) {
|
|
265
|
+
return pending;
|
|
266
|
+
}
|
|
267
|
+
const validationError = validateExtendedTextSubmission(ctx.log, values, minStrings, maxStrings);
|
|
268
|
+
if (validationError) {
|
|
269
|
+
return Promise.resolve(ctx.errored(validationError, "interaction", {
|
|
270
|
+
kind: "interaction",
|
|
271
|
+
submission: { type: "extended-text", values }
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
pending = ctx.execute({ kind: "interaction", submission: { type: "extended-text", values } }, "interaction");
|
|
275
|
+
return pending;
|
|
276
|
+
},
|
|
277
|
+
timeout: function timeout() {
|
|
278
|
+
if (pending) {
|
|
279
|
+
return pending;
|
|
280
|
+
}
|
|
281
|
+
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
282
|
+
return pending;
|
|
283
|
+
},
|
|
284
|
+
toJSON: poisonToJSON
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// src/feedback-state.ts
|
|
289
|
+
function feedbackState(ctx, stimulus, interaction, submission, isCorrect, feedbackContent, correctAnswer) {
|
|
290
|
+
let pending;
|
|
291
|
+
return {
|
|
292
|
+
phase: "feedback",
|
|
293
|
+
stimulus,
|
|
294
|
+
interaction,
|
|
295
|
+
submission,
|
|
296
|
+
isCorrect,
|
|
297
|
+
feedbackContent,
|
|
298
|
+
correctAnswer,
|
|
299
|
+
advance: function advance() {
|
|
300
|
+
if (pending) {
|
|
301
|
+
return pending;
|
|
302
|
+
}
|
|
303
|
+
pending = ctx.execute({ kind: "observation" }, "observation");
|
|
304
|
+
return pending;
|
|
305
|
+
},
|
|
306
|
+
toJSON: poisonToJSON
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/observation-state.ts
|
|
311
|
+
function observationState(ctx, stimulus) {
|
|
312
|
+
let pending;
|
|
313
|
+
return {
|
|
314
|
+
phase: "observation",
|
|
315
|
+
stimulus,
|
|
316
|
+
advance: function advance() {
|
|
317
|
+
if (pending) {
|
|
318
|
+
return pending;
|
|
319
|
+
}
|
|
320
|
+
pending = ctx.execute({ kind: "observation" }, "observation");
|
|
321
|
+
return pending;
|
|
322
|
+
},
|
|
323
|
+
toJSON: poisonToJSON
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/pci-state.ts
|
|
328
|
+
function pciInteractionState(ctx, stimulus, interaction) {
|
|
329
|
+
let pending;
|
|
330
|
+
const { pciId, properties } = interaction;
|
|
331
|
+
function submit(value) {
|
|
332
|
+
if (pending) {
|
|
333
|
+
return pending;
|
|
334
|
+
}
|
|
335
|
+
ctx.log?.debug("pci submit", { pciId });
|
|
336
|
+
const submission = { type: "portable-custom", pciId, value };
|
|
337
|
+
pending = ctx.execute({ kind: "interaction", submission }, "interaction");
|
|
338
|
+
return pending;
|
|
339
|
+
}
|
|
340
|
+
function timeout() {
|
|
341
|
+
if (pending) {
|
|
342
|
+
return pending;
|
|
343
|
+
}
|
|
344
|
+
ctx.log?.debug("pci timeout", { pciId });
|
|
345
|
+
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
346
|
+
return pending;
|
|
347
|
+
}
|
|
348
|
+
return {
|
|
349
|
+
phase: "interaction",
|
|
350
|
+
kind: "portable-custom",
|
|
351
|
+
stimulus,
|
|
352
|
+
interaction,
|
|
353
|
+
pciId,
|
|
354
|
+
properties,
|
|
355
|
+
submit,
|
|
356
|
+
timeout,
|
|
357
|
+
toJSON: poisonToJSON
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// src/text-entry-state.ts
|
|
362
|
+
function textEntryState(ctx, stimulus, interaction) {
|
|
363
|
+
let pending;
|
|
364
|
+
return {
|
|
365
|
+
phase: "interaction",
|
|
366
|
+
kind: "text-entry",
|
|
367
|
+
stimulus,
|
|
368
|
+
interaction,
|
|
369
|
+
submitText: function submitText(value) {
|
|
370
|
+
if (pending) {
|
|
371
|
+
return pending;
|
|
372
|
+
}
|
|
373
|
+
pending = ctx.execute({ kind: "interaction", submission: { type: "text-entry", value } }, "interaction");
|
|
374
|
+
return pending;
|
|
375
|
+
},
|
|
376
|
+
timeout: function timeout() {
|
|
377
|
+
if (pending) {
|
|
378
|
+
return pending;
|
|
379
|
+
}
|
|
380
|
+
pending = ctx.execute({ kind: "timeout" }, "timeout");
|
|
381
|
+
return pending;
|
|
382
|
+
},
|
|
383
|
+
toJSON: poisonToJSON
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// src/session.ts
|
|
388
|
+
var FATAL_SENTINELS = [
|
|
389
|
+
ErrBadRequest,
|
|
390
|
+
ErrInvalidPublishableKey,
|
|
391
|
+
ErrForbidden,
|
|
392
|
+
ErrNotFound,
|
|
393
|
+
ErrUnsupportedPci
|
|
394
|
+
];
|
|
395
|
+
function isFatalError(err) {
|
|
396
|
+
for (const sentinel of FATAL_SENTINELS) {
|
|
397
|
+
if (errors5.is(err, sentinel)) {
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
function makeSession(sc) {
|
|
404
|
+
const log = sc.log;
|
|
405
|
+
function resolve(result) {
|
|
406
|
+
switch (result.outcome) {
|
|
407
|
+
case "advanced":
|
|
408
|
+
return fromAdvanced(result.stimulus, result.interaction);
|
|
409
|
+
case "submitted":
|
|
410
|
+
return feedbackState(ctx, result.stimulus, result.interaction, result.submission, result.isCorrect, result.feedbackContent, result.correctAnswer);
|
|
411
|
+
case "completed":
|
|
412
|
+
return { phase: "completed", toJSON: poisonToJSON };
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function errored(error, failedPhase, intent) {
|
|
416
|
+
let pending;
|
|
417
|
+
return {
|
|
418
|
+
phase: "errored",
|
|
419
|
+
error,
|
|
420
|
+
failedPhase,
|
|
421
|
+
retry: function retry() {
|
|
422
|
+
if (pending) {
|
|
423
|
+
return pending;
|
|
424
|
+
}
|
|
425
|
+
log?.debug("retrying from errored state", { failedPhase });
|
|
426
|
+
pending = execute(intent, failedPhase);
|
|
427
|
+
return pending;
|
|
428
|
+
},
|
|
429
|
+
toJSON: poisonToJSON
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
async function execute(intent, phase) {
|
|
433
|
+
const body = {
|
|
434
|
+
studentId: sc.studentId,
|
|
435
|
+
supportedPcis: sc.supportedPcis,
|
|
436
|
+
intent
|
|
437
|
+
};
|
|
438
|
+
const result = await sc.transport(body);
|
|
439
|
+
if (!result.ok) {
|
|
440
|
+
if (isFatalError(result.error)) {
|
|
441
|
+
log?.error("fatal transport error", { error: result.error, phase });
|
|
442
|
+
return { phase: "fatal", error: result.error, toJSON: poisonToJSON };
|
|
443
|
+
}
|
|
444
|
+
return errored(result.error, phase, intent);
|
|
445
|
+
}
|
|
446
|
+
return resolve(result.data);
|
|
447
|
+
}
|
|
448
|
+
function isPciSupported(pciId) {
|
|
449
|
+
for (const id of sc.supportedPcis) {
|
|
450
|
+
if (id === pciId) {
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
function fromAdvanced(stimulus, interaction) {
|
|
457
|
+
if (interaction === null) {
|
|
458
|
+
return observationState(ctx, stimulus);
|
|
459
|
+
}
|
|
460
|
+
if (interaction.type === "portable-custom") {
|
|
461
|
+
if (!isPciSupported(interaction.pciId)) {
|
|
462
|
+
log?.error("unsupported pci in frame", { pciId: interaction.pciId });
|
|
463
|
+
return {
|
|
464
|
+
phase: "fatal",
|
|
465
|
+
error: errors5.wrap(ErrUnsupportedPci, `pci '${interaction.pciId}'`),
|
|
466
|
+
toJSON: poisonToJSON
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return pendingInteractionState(stimulus, interaction);
|
|
471
|
+
}
|
|
472
|
+
function pendingInteractionState(stimulus, interaction) {
|
|
473
|
+
switch (interaction.type) {
|
|
474
|
+
case "choice":
|
|
475
|
+
return choiceState(ctx, stimulus, interaction, interaction.options, interaction.maxChoices, interaction.minChoices);
|
|
476
|
+
case "text-entry":
|
|
477
|
+
return textEntryState(ctx, stimulus, interaction);
|
|
478
|
+
case "extended-text":
|
|
479
|
+
return extendedTextState(ctx, stimulus, interaction);
|
|
480
|
+
case "portable-custom":
|
|
481
|
+
return pciInteractionState(ctx, stimulus, interaction);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
const ctx = { log, execute, errored };
|
|
485
|
+
return { execute };
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// src/client.ts
|
|
489
|
+
var DEFAULT_ORIGIN = "https://sb-primer.vercel.app";
|
|
490
|
+
var PK_PREFIX = "pk_";
|
|
491
|
+
function create(config) {
|
|
492
|
+
const log = config.logger;
|
|
493
|
+
if (!config.publishableKey.startsWith(PK_PREFIX)) {
|
|
494
|
+
log?.error("malformed publishable key", { prefix: PK_PREFIX });
|
|
495
|
+
throw errors6.wrap(ErrMalformedPublishableKey, `key must start with '${PK_PREFIX}'`);
|
|
496
|
+
}
|
|
497
|
+
const transport = createTransport({
|
|
498
|
+
publishableKey: config.publishableKey,
|
|
499
|
+
supportedPcis: config.supportedPcis,
|
|
500
|
+
origin: config.origin,
|
|
501
|
+
fetch: config.fetch,
|
|
502
|
+
abort: config.abort,
|
|
503
|
+
log
|
|
504
|
+
});
|
|
505
|
+
let startPromise;
|
|
506
|
+
async function doStart(studentId) {
|
|
507
|
+
log?.debug("start", { studentId });
|
|
508
|
+
const s = makeSession({
|
|
509
|
+
studentId,
|
|
510
|
+
supportedPcis: config.supportedPcis,
|
|
511
|
+
log,
|
|
512
|
+
transport
|
|
513
|
+
});
|
|
514
|
+
return s.execute({ kind: "observation" }, "observation");
|
|
515
|
+
}
|
|
516
|
+
return {
|
|
517
|
+
start(studentId) {
|
|
518
|
+
if (startPromise) {
|
|
519
|
+
log?.debug("start already called");
|
|
520
|
+
return startPromise;
|
|
521
|
+
}
|
|
522
|
+
startPromise = doStart(studentId);
|
|
523
|
+
return startPromise;
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
// src/content.ts
|
|
528
|
+
function inlinesToPlainText(nodes) {
|
|
529
|
+
const parts = [];
|
|
530
|
+
for (const node of nodes) {
|
|
531
|
+
switch (node.type) {
|
|
532
|
+
case "text":
|
|
533
|
+
parts.push(node.value);
|
|
534
|
+
break;
|
|
535
|
+
case "italic":
|
|
536
|
+
parts.push(inlinesToPlainText(node.children));
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return parts.join("");
|
|
541
|
+
}
|
|
542
|
+
function blocksToPlainText(blocks) {
|
|
543
|
+
return blocks.map(function blockText(block) {
|
|
544
|
+
return inlinesToPlainText(block.children);
|
|
545
|
+
}).join(`
|
|
546
|
+
`);
|
|
547
|
+
}
|
|
548
|
+
export {
|
|
549
|
+
inlinesToPlainText,
|
|
550
|
+
create,
|
|
551
|
+
blocksToPlainText,
|
|
552
|
+
ErrUnsupportedPci,
|
|
553
|
+
ErrTimeout,
|
|
554
|
+
ErrServiceUnavailable,
|
|
555
|
+
ErrServerError,
|
|
556
|
+
ErrRateLimited,
|
|
557
|
+
ErrNotSerializable,
|
|
558
|
+
ErrNotFound,
|
|
559
|
+
ErrNetwork,
|
|
560
|
+
ErrMalformedPublishableKey,
|
|
561
|
+
ErrJsonParse,
|
|
562
|
+
ErrInvalidSubmission,
|
|
563
|
+
ErrInvalidPublishableKey,
|
|
564
|
+
ErrForbidden,
|
|
565
|
+
ErrConflict,
|
|
566
|
+
ErrBadRequest,
|
|
567
|
+
DEFAULT_ORIGIN,
|
|
568
|
+
ADVANCE_PATH
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
//# debugId=FDEA35E8106B1EE164756E2164756E21
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client.ts", "../src/errors.ts", "../src/transport.ts", "../src/session.ts", "../src/consumed.ts", "../src/choice-state.ts", "../src/extended-text-state.ts", "../src/feedback-state.ts", "../src/observation-state.ts", "../src/pci-state.ts", "../src/text-entry-state.ts", "../src/content.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import * as errors from \"@superbuilders/errors\"\nimport { ErrMalformedPublishableKey } from \"@superbuilders/primer-tives/errors\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type { PrimerLogger } from \"@superbuilders/primer-tives/session-context\"\nimport type { PrimerState } from \"@superbuilders/primer-tives/types\"\nimport { createTransport } from \"@superbuilders/primer-tives/transport\"\nimport { makeSession } from \"@superbuilders/primer-tives/session\"\n\nconst DEFAULT_ORIGIN = \"https://sb-primer.vercel.app\"\nconst PK_PREFIX = \"pk_\"\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 create<const Pcis extends PciId>(config: Config<Pcis>): Client<Pcis> {\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\tconst transport = createTransport({\n\t\tpublishableKey: config.publishableKey,\n\t\tsupportedPcis: config.supportedPcis,\n\t\torigin: config.origin,\n\t\tfetch: config.fetch,\n\t\tabort: config.abort,\n\t\tlog\n\t})\n\n\tlet startPromise: Promise<PrimerState<Pcis>> | undefined\n\n\tasync function doStart(studentId: string): Promise<PrimerState<Pcis>> {\n\t\tlog?.debug(\"start\", { studentId })\n\t\tconst s = makeSession({\n\t\t\tstudentId,\n\t\t\tsupportedPcis: config.supportedPcis,\n\t\t\tlog,\n\t\t\ttransport\n\t\t})\n\t\treturn s.execute({ kind: \"observation\" }, \"observation\")\n\t}\n\n\treturn {\n\t\tstart(studentId: string): Promise<PrimerState<Pcis>> {\n\t\t\tif (startPromise) {\n\t\t\t\tlog?.debug(\"start already called\")\n\t\t\t\treturn startPromise\n\t\t\t}\n\t\t\tstartPromise = doStart(studentId)\n\t\t\treturn startPromise\n\t\t}\n\t}\n}\n\nexport { DEFAULT_ORIGIN, create }\nexport type { Client, Config, PrimerLogger }\n",
|
|
6
|
+
"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",
|
|
7
|
+
"import * as errors from \"@superbuilders/errors\"\nimport {\n\tErrBadRequest,\n\tErrConflict,\n\tErrForbidden,\n\tErrInvalidPublishableKey,\n\tErrJsonParse,\n\tErrNetwork,\n\tErrNotFound,\n\tErrRateLimited,\n\tErrServerError,\n\tErrServiceUnavailable,\n\tErrTimeout,\n\tErrUnsupportedPci\n} from \"@superbuilders/primer-tives/errors\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type { SessionContext, WireIntent } from \"@superbuilders/primer-tives/session-context\"\nimport type { ContentInline } from \"@superbuilders/primer-tives/content\"\nimport type {\n\tRendererCorrectAnswer,\n\tRendererInteraction,\n\tRendererStimulus,\n\tRendererSubmission\n} from \"@superbuilders/primer-tives/types\"\n\nconst ADVANCE_PATH = \"/api/v0/advance\"\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\ninterface TransportConfig<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 log: SessionContext[\"log\"]\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\nfunction createTransport<Pcis extends PciId>(tc: TransportConfig<Pcis>) {\n\tconst fetchFn = tc.fetch ? tc.fetch : globalThis.fetch\n\tconst log = tc.log\n\n\tfunction transportSignal(): AbortSignal | undefined {\n\t\tif (tc.abort) {\n\t\t\treturn tc.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 = tc.origin ? `${tc.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\": tc.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\treturn transport\n}\n\nexport { ADVANCE_PATH, createTransport, httpSentinel, isAbortError }\nexport type { TransportConfig, TransportResult, WireRequestBody, WireResult }\n",
|
|
8
|
+
"import * as errors from \"@superbuilders/errors\"\nimport { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport {\n\tErrBadRequest,\n\tErrForbidden,\n\tErrInvalidPublishableKey,\n\tErrNotFound,\n\tErrUnsupportedPci\n} from \"@superbuilders/primer-tives/errors\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type {\n\tPrimerLogger,\n\tSessionContext,\n\tTransitionPhase,\n\tWireIntent\n} from \"@superbuilders/primer-tives/session-context\"\nimport type {\n\tTransportResult,\n\tWireRequestBody,\n\tWireResult\n} from \"@superbuilders/primer-tives/transport\"\nimport type {\n\tErroredState,\n\tPrimerState,\n\tRendererInteraction,\n\tRendererStimulus\n} from \"@superbuilders/primer-tives/types\"\nimport { choiceState } from \"@superbuilders/primer-tives/choice-state\"\nimport { extendedTextState } from \"@superbuilders/primer-tives/extended-text-state\"\nimport { feedbackState } from \"@superbuilders/primer-tives/feedback-state\"\nimport { observationState } from \"@superbuilders/primer-tives/observation-state\"\nimport { pciInteractionState } from \"@superbuilders/primer-tives/pci-state\"\nimport { textEntryState } from \"@superbuilders/primer-tives/text-entry-state\"\n\ninterface SessionConfig<Pcis extends PciId = PciId> {\n\treadonly studentId: string\n\treadonly supportedPcis: readonly Pcis[]\n\treadonly log: PrimerLogger | undefined\n\treadonly transport: (body: WireRequestBody<Pcis>) => Promise<TransportResult<Pcis>>\n}\n\nconst FATAL_SENTINELS = [\n\tErrBadRequest,\n\tErrInvalidPublishableKey,\n\tErrForbidden,\n\tErrNotFound,\n\tErrUnsupportedPci\n]\n\nfunction isFatalError(err: Error): boolean {\n\tfor (const sentinel of FATAL_SENTINELS) {\n\t\tif (errors.is(err, sentinel)) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunction makeSession<Pcis extends PciId>(sc: SessionConfig<Pcis>) {\n\tconst log = sc.log\n\n\tfunction resolve(result: WireResult<Pcis>): PrimerState<Pcis> {\n\t\tswitch (result.outcome) {\n\t\t\tcase \"advanced\":\n\t\t\t\treturn fromAdvanced(result.stimulus, result.interaction)\n\t\t\tcase \"submitted\":\n\t\t\t\treturn feedbackState(\n\t\t\t\t\tctx,\n\t\t\t\t\tresult.stimulus,\n\t\t\t\t\tresult.interaction,\n\t\t\t\t\tresult.submission,\n\t\t\t\t\tresult.isCorrect,\n\t\t\t\t\tresult.feedbackContent,\n\t\t\t\t\tresult.correctAnswer\n\t\t\t\t)\n\t\t\tcase \"completed\":\n\t\t\t\treturn { phase: \"completed\", toJSON: poisonToJSON }\n\t\t}\n\t}\n\n\tfunction errored(\n\t\terror: Error,\n\t\tfailedPhase: TransitionPhase,\n\t\tintent: WireIntent<Pcis>\n\t): ErroredState<Pcis> {\n\t\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\t\treturn {\n\t\t\tphase: \"errored\",\n\t\t\terror,\n\t\t\tfailedPhase,\n\t\t\tretry: function retry() {\n\t\t\t\tif (pending) {\n\t\t\t\t\treturn pending\n\t\t\t\t}\n\t\t\t\tlog?.debug(\"retrying from errored state\", { failedPhase })\n\t\t\t\tpending = execute(intent, failedPhase)\n\t\t\t\treturn pending\n\t\t\t},\n\t\t\ttoJSON: poisonToJSON\n\t\t}\n\t}\n\n\tasync function execute(\n\t\tintent: WireIntent<Pcis>,\n\t\tphase: TransitionPhase\n\t): Promise<PrimerState<Pcis>> {\n\t\tconst body: WireRequestBody<Pcis> = {\n\t\t\tstudentId: sc.studentId,\n\t\t\tsupportedPcis: sc.supportedPcis,\n\t\t\tintent\n\t\t}\n\n\t\tconst result = await sc.transport(body)\n\t\tif (!result.ok) {\n\t\t\tif (isFatalError(result.error)) {\n\t\t\t\tlog?.error(\"fatal transport error\", { error: result.error, phase })\n\t\t\t\treturn { phase: \"fatal\", error: result.error, toJSON: poisonToJSON }\n\t\t\t}\n\t\t\treturn errored(result.error, phase, intent)\n\t\t}\n\n\t\treturn resolve(result.data)\n\t}\n\n\tfunction isPciSupported(pciId: string): boolean {\n\t\tfor (const id of sc.supportedPcis) {\n\t\t\tif (id === pciId) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tfunction fromAdvanced(\n\t\tstimulus: RendererStimulus | null,\n\t\tinteraction: RendererInteraction<Pcis> | null\n\t): PrimerState<Pcis> {\n\t\tif (interaction === null) {\n\t\t\treturn observationState(ctx, stimulus)\n\t\t}\n\t\tif (interaction.type === \"portable-custom\") {\n\t\t\tif (!isPciSupported(interaction.pciId)) {\n\t\t\t\tlog?.error(\"unsupported pci in frame\", { pciId: interaction.pciId })\n\t\t\t\treturn {\n\t\t\t\t\tphase: \"fatal\",\n\t\t\t\t\terror: errors.wrap(ErrUnsupportedPci, `pci '${interaction.pciId}'`),\n\t\t\t\t\ttoJSON: poisonToJSON\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn pendingInteractionState(stimulus, interaction)\n\t}\n\n\tfunction pendingInteractionState(\n\t\tstimulus: RendererStimulus | null,\n\t\tinteraction: RendererInteraction<Pcis>\n\t): PrimerState<Pcis> {\n\t\tswitch (interaction.type) {\n\t\t\tcase \"choice\":\n\t\t\t\treturn choiceState(\n\t\t\t\t\tctx,\n\t\t\t\t\tstimulus,\n\t\t\t\t\tinteraction,\n\t\t\t\t\tinteraction.options,\n\t\t\t\t\tinteraction.maxChoices,\n\t\t\t\t\tinteraction.minChoices\n\t\t\t\t)\n\t\t\tcase \"text-entry\":\n\t\t\t\treturn textEntryState(ctx, stimulus, interaction)\n\t\t\tcase \"extended-text\":\n\t\t\t\treturn extendedTextState(ctx, stimulus, interaction)\n\t\t\tcase \"portable-custom\":\n\t\t\t\treturn pciInteractionState(ctx, stimulus, interaction)\n\t\t}\n\t}\n\n\tconst ctx: SessionContext<Pcis> = { log, execute, errored }\n\n\treturn { execute }\n}\n\nexport { makeSession }\nexport type { SessionConfig }\n",
|
|
9
|
+
"import { ErrNotSerializable } from \"@superbuilders/primer-tives/errors\"\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\nexport { poisonToJSON }\n",
|
|
10
|
+
"import { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport { ErrInvalidSubmission } from \"@superbuilders/primer-tives/errors\"\nimport type { SessionContext } from \"@superbuilders/primer-tives/session-context\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type {\n\tPrimerState,\n\tRendererChoice,\n\tRendererInteraction,\n\tRendererStimulus\n} from \"@superbuilders/primer-tives/types\"\nimport * as errors from \"@superbuilders/errors\"\n\nfunction findUnknownKey(selectedKeys: string[], options: RendererChoice[]): string | null {\n\tconst optionIds = new Set(\n\t\toptions.map(function getId(o) {\n\t\t\treturn o.identifier\n\t\t})\n\t)\n\tfor (const key of selectedKeys) {\n\t\tif (!optionIds.has(key)) {\n\t\t\treturn key\n\t\t}\n\t}\n\treturn null\n}\n\nfunction validateChoiceSubmission(\n\tlog: SessionContext[\"log\"],\n\tselectedKeys: string[],\n\toptions: RendererChoice[],\n\tmaxChoices: number,\n\tminChoices: number\n): Error | null {\n\tif (selectedKeys.length < minChoices) {\n\t\tlog?.error(\"choice submit below minChoices\", { selectedKeys, minChoices })\n\t\treturn errors.wrap(ErrInvalidSubmission, `need at least ${minChoices} selections`)\n\t}\n\tif (selectedKeys.length > maxChoices) {\n\t\tlog?.error(\"choice submit above maxChoices\", { selectedKeys, maxChoices })\n\t\treturn errors.wrap(ErrInvalidSubmission, `at most ${maxChoices} selections`)\n\t}\n\tconst uniqueKeys = new Set(selectedKeys)\n\tif (uniqueKeys.size !== selectedKeys.length) {\n\t\tlog?.error(\"choice submit has duplicates\", { selectedKeys })\n\t\treturn errors.wrap(ErrInvalidSubmission, \"duplicate selections\")\n\t}\n\tconst unknownKey = findUnknownKey(selectedKeys, options)\n\tif (unknownKey) {\n\t\tlog?.error(\"choice submit has unknown key\", { key: unknownKey })\n\t\treturn errors.wrap(ErrInvalidSubmission, `unknown option '${unknownKey}'`)\n\t}\n\treturn null\n}\n\nfunction choiceState<Pcis extends PciId>(\n\tctx: SessionContext<Pcis>,\n\tstimulus: RendererStimulus | null,\n\tinteraction: Extract<RendererInteraction<Pcis>, { type: \"choice\" }>,\n\toptions: RendererChoice[],\n\tmaxChoices: number,\n\tminChoices: number\n): PrimerState<Pcis> {\n\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\treturn {\n\t\tphase: \"interaction\",\n\t\tkind: \"choice\",\n\t\tstimulus,\n\t\tinteraction,\n\t\toptions,\n\t\tmaxChoices,\n\t\tminChoices,\n\t\tsubmitChoice: function submitChoice(selectedKeys: string[]) {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tconst validationError = validateChoiceSubmission(\n\t\t\t\tctx.log,\n\t\t\t\tselectedKeys,\n\t\t\t\toptions,\n\t\t\t\tmaxChoices,\n\t\t\t\tminChoices\n\t\t\t)\n\t\t\tif (validationError) {\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tctx.errored(validationError, \"interaction\", {\n\t\t\t\t\t\tkind: \"interaction\",\n\t\t\t\t\t\tsubmission: { type: \"choice\", selectedKeys }\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t}\n\t\t\tpending = ctx.execute(\n\t\t\t\t{ kind: \"interaction\", submission: { type: \"choice\", selectedKeys } },\n\t\t\t\t\"interaction\"\n\t\t\t)\n\t\t\treturn pending\n\t\t},\n\t\ttimeout: function timeout() {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tpending = ctx.execute({ kind: \"timeout\" }, \"timeout\")\n\t\t\treturn pending\n\t\t},\n\t\ttoJSON: poisonToJSON\n\t}\n}\n\nexport { choiceState }\n",
|
|
11
|
+
"import { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport { ErrInvalidSubmission } from \"@superbuilders/primer-tives/errors\"\nimport type { SessionContext } from \"@superbuilders/primer-tives/session-context\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type {\n\tPrimerState,\n\tRendererInteraction,\n\tRendererStimulus\n} from \"@superbuilders/primer-tives/types\"\nimport * as errors from \"@superbuilders/errors\"\n\nfunction validateExtendedTextSubmission(\n\tlog: SessionContext[\"log\"],\n\tvalues: string[],\n\tminStrings: number,\n\tmaxStrings: number\n): Error | null {\n\tif (values.length < minStrings) {\n\t\tlog?.error(\"extended-text submit below minStrings\", { count: values.length, minStrings })\n\t\treturn errors.wrap(ErrInvalidSubmission, `need at least ${minStrings} values`)\n\t}\n\tif (values.length > maxStrings) {\n\t\tlog?.error(\"extended-text submit above maxStrings\", { count: values.length, maxStrings })\n\t\treturn errors.wrap(ErrInvalidSubmission, `at most ${maxStrings} values`)\n\t}\n\treturn null\n}\n\nfunction extendedTextState<Pcis extends PciId>(\n\tctx: SessionContext<Pcis>,\n\tstimulus: RendererStimulus | null,\n\tinteraction: RendererInteraction<Pcis> & { type: \"extended-text\" }\n): PrimerState<Pcis> {\n\tconst maxStrings = interaction.maxStrings\n\tconst minStrings = interaction.minStrings\n\tif (maxStrings === 1) {\n\t\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\t\treturn {\n\t\t\tphase: \"interaction\",\n\t\t\tkind: \"extended-text\",\n\t\t\tcardinality: \"single\",\n\t\t\tstimulus,\n\t\t\tinteraction,\n\t\t\tsubmitText: function submitText(value: string) {\n\t\t\t\tif (pending) {\n\t\t\t\t\treturn pending\n\t\t\t\t}\n\t\t\t\tpending = ctx.execute(\n\t\t\t\t\t{ kind: \"interaction\", submission: { type: \"extended-text\", values: [value] } },\n\t\t\t\t\t\"interaction\"\n\t\t\t\t)\n\t\t\t\treturn pending\n\t\t\t},\n\t\t\ttimeout: function timeout() {\n\t\t\t\tif (pending) {\n\t\t\t\t\treturn pending\n\t\t\t\t}\n\t\t\t\tpending = ctx.execute({ kind: \"timeout\" }, \"timeout\")\n\t\t\t\treturn pending\n\t\t\t},\n\t\t\ttoJSON: poisonToJSON\n\t\t}\n\t}\n\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\treturn {\n\t\tphase: \"interaction\",\n\t\tkind: \"extended-text\",\n\t\tcardinality: \"multiple\",\n\t\tstimulus,\n\t\tinteraction,\n\t\tmaxStrings,\n\t\tminStrings,\n\t\tsubmitTexts: function submitTexts(values: string[]) {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tconst validationError = validateExtendedTextSubmission(\n\t\t\t\tctx.log,\n\t\t\t\tvalues,\n\t\t\t\tminStrings,\n\t\t\t\tmaxStrings\n\t\t\t)\n\t\t\tif (validationError) {\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\tctx.errored(validationError, \"interaction\", {\n\t\t\t\t\t\tkind: \"interaction\",\n\t\t\t\t\t\tsubmission: { type: \"extended-text\", values }\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t}\n\t\t\tpending = ctx.execute(\n\t\t\t\t{ kind: \"interaction\", submission: { type: \"extended-text\", values } },\n\t\t\t\t\"interaction\"\n\t\t\t)\n\t\t\treturn pending\n\t\t},\n\t\ttimeout: function timeout() {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tpending = ctx.execute({ kind: \"timeout\" }, \"timeout\")\n\t\t\treturn pending\n\t\t},\n\t\ttoJSON: poisonToJSON\n\t}\n}\n\nexport { extendedTextState }\n",
|
|
12
|
+
"import { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport type { ContentInline } from \"@superbuilders/primer-tives/content\"\nimport type { SessionContext } from \"@superbuilders/primer-tives/session-context\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type {\n\tPrimerState,\n\tRendererCorrectAnswer,\n\tRendererInteraction,\n\tRendererStimulus,\n\tRendererSubmission\n} from \"@superbuilders/primer-tives/types\"\n\nfunction feedbackState<Pcis extends PciId>(\n\tctx: SessionContext<Pcis>,\n\tstimulus: RendererStimulus | null,\n\tinteraction: RendererInteraction<Pcis>,\n\tsubmission: RendererSubmission<Pcis>,\n\tisCorrect: boolean,\n\tfeedbackContent: ContentInline[],\n\tcorrectAnswer: RendererCorrectAnswer | null\n): PrimerState<Pcis> {\n\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\treturn {\n\t\tphase: \"feedback\",\n\t\tstimulus,\n\t\tinteraction,\n\t\tsubmission,\n\t\tisCorrect,\n\t\tfeedbackContent,\n\t\tcorrectAnswer,\n\t\tadvance: function advance() {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tpending = ctx.execute({ kind: \"observation\" }, \"observation\")\n\t\t\treturn pending\n\t\t},\n\t\ttoJSON: poisonToJSON\n\t}\n}\n\nexport { feedbackState }\n",
|
|
13
|
+
"import { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport type { SessionContext } from \"@superbuilders/primer-tives/session-context\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type { PrimerState, RendererStimulus } from \"@superbuilders/primer-tives/types\"\n\nfunction observationState<Pcis extends PciId>(\n\tctx: SessionContext<Pcis>,\n\tstimulus: RendererStimulus | null\n): PrimerState<Pcis> {\n\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\treturn {\n\t\tphase: \"observation\",\n\t\tstimulus,\n\t\tadvance: function advance() {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tpending = ctx.execute({ kind: \"observation\" }, \"observation\")\n\t\t\treturn pending\n\t\t},\n\t\ttoJSON: poisonToJSON\n\t}\n}\n\nexport { observationState }\n",
|
|
14
|
+
"import { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport type { PciId, PciValue } from \"@superbuilders/primer-tives/pci\"\nimport type { SessionContext } from \"@superbuilders/primer-tives/session-context\"\nimport type {\n\tPciInteraction,\n\tPciInteractionState,\n\tPrimerState,\n\tRendererStimulus\n} from \"@superbuilders/primer-tives/types\"\n\nfunction pciInteractionState<Pcis extends PciId>(\n\tctx: SessionContext<Pcis>,\n\tstimulus: RendererStimulus | null,\n\tinteraction: PciInteraction<Pcis>\n): PciInteractionState<Pcis> {\n\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\tconst { pciId, properties } = interaction\n\tfunction submit(value: PciValue<typeof pciId>): Promise<PrimerState<Pcis>> {\n\t\tif (pending) {\n\t\t\treturn pending\n\t\t}\n\t\tctx.log?.debug(\"pci submit\", { pciId })\n\t\tconst submission = { type: \"portable-custom\" as const, pciId, value }\n\t\tpending = ctx.execute({ kind: \"interaction\", submission }, \"interaction\")\n\t\treturn pending\n\t}\n\tfunction timeout(): Promise<PrimerState<Pcis>> {\n\t\tif (pending) {\n\t\t\treturn pending\n\t\t}\n\t\tctx.log?.debug(\"pci timeout\", { pciId })\n\t\tpending = ctx.execute({ kind: \"timeout\" }, \"timeout\")\n\t\treturn pending\n\t}\n\t// biome-ignore lint/plugin: TS cannot verify mapped-union construction from generic Pcis — pciId↔properties correlation preserved by input\n\treturn {\n\t\tphase: \"interaction\",\n\t\tkind: \"portable-custom\",\n\t\tstimulus,\n\t\tinteraction,\n\t\tpciId,\n\t\tproperties,\n\t\tsubmit,\n\t\ttimeout,\n\t\ttoJSON: poisonToJSON\n\t} as PciInteractionState<Pcis>\n}\n\nexport { pciInteractionState }\n",
|
|
15
|
+
"import { poisonToJSON } from \"@superbuilders/primer-tives/consumed\"\nimport type { SessionContext } from \"@superbuilders/primer-tives/session-context\"\nimport type { PciId } from \"@superbuilders/primer-tives/pci\"\nimport type {\n\tPrimerState,\n\tRendererInteraction,\n\tRendererStimulus\n} from \"@superbuilders/primer-tives/types\"\n\nfunction textEntryState<Pcis extends PciId>(\n\tctx: SessionContext<Pcis>,\n\tstimulus: RendererStimulus | null,\n\tinteraction: Extract<RendererInteraction<Pcis>, { type: \"text-entry\" }>\n): PrimerState<Pcis> {\n\tlet pending: Promise<PrimerState<Pcis>> | undefined\n\treturn {\n\t\tphase: \"interaction\",\n\t\tkind: \"text-entry\",\n\t\tstimulus,\n\t\tinteraction,\n\t\tsubmitText: function submitText(value: string) {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tpending = ctx.execute(\n\t\t\t\t{ kind: \"interaction\", submission: { type: \"text-entry\", value } },\n\t\t\t\t\"interaction\"\n\t\t\t)\n\t\t\treturn pending\n\t\t},\n\t\ttimeout: function timeout() {\n\t\t\tif (pending) {\n\t\t\t\treturn pending\n\t\t\t}\n\t\t\tpending = ctx.execute({ kind: \"timeout\" }, \"timeout\")\n\t\t\treturn pending\n\t\t},\n\t\ttoJSON: poisonToJSON\n\t}\n}\n\nexport { textEntryState }\n",
|
|
16
|
+
"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"
|
|
17
|
+
],
|
|
18
|
+
"mappings": "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",
|
|
19
|
+
"debugId": "FDEA35E8106B1EE164756E2164756E21",
|
|
20
|
+
"names": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SessionContext } from "./session-context";
|
|
2
|
+
import type { PciId } from "./pci";
|
|
3
|
+
import type { PrimerState, RendererStimulus } from "./types";
|
|
4
|
+
declare function observationState<Pcis extends PciId>(ctx: SessionContext<Pcis>, stimulus: RendererStimulus | null): PrimerState<Pcis>;
|
|
5
|
+
export { observationState };
|
|
6
|
+
//# sourceMappingURL=observation-state.d.ts.map
|