@edpire/sdk 0.5.0 → 0.6.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/dist/react.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { RuntimeAnswer, AssessmentContent, AssessmentAnswers, QuestionRuntimeProps } from '@youssefalmia/edpire-runtime';
2
+ import { RuntimeAnswer, QuestionRuntimeProps, AssessmentContent, AssessmentAnswers } from '@youssefalmia/edpire-runtime';
3
3
  export { RuntimeAnswer } from '@youssefalmia/edpire-runtime';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { RichContent } from '@youssefalmia/edpire-schema/authoring';
@@ -52,32 +52,6 @@ interface EdpireQuestionProps {
52
52
  }
53
53
  declare const EdpireQuestion: React.NamedExoticComponent<EdpireQuestionProps>;
54
54
 
55
- type SpinnerTheme = "default" | "dots" | "pulse" | "bars";
56
- interface GradingOverlayProps {
57
- visible: boolean;
58
- bgColor?: string;
59
- accentColor?: string;
60
- text?: string;
61
- aiText?: string;
62
- spinnerTheme?: SpinnerTheme;
63
- animationUrl?: string;
64
- hasAiNodes?: boolean;
65
- contained?: boolean;
66
- }
67
- type OverlayConfig = Pick<GradingOverlayProps, "bgColor" | "accentColor" | "text" | "spinnerTheme" | "animationUrl">;
68
-
69
- /**
70
- * Standalone, dependency-free i18n for the SDK shell.
71
- *
72
- * Replaces the web app's `useTranslations("learner.taking")` so the shell can
73
- * be rendered in any React environment (Vite, CRA, Astro, UMD CDN, mobile
74
- * WebView). Locale is passed as a prop — there is no React context to set up.
75
- *
76
- * Strings mirror `packages/i18n/messages/{en,fr,ar}.json` under `learner.taking.*`.
77
- * Keep in sync if those copies are edited.
78
- */
79
- type ShellLocale = "en" | "fr" | "ar";
80
-
81
55
  /**
82
56
  * Public types for the polished Assessment Shell.
83
57
  *
@@ -152,6 +126,208 @@ interface SubmitResult {
152
126
  awaitingManualGrading?: boolean;
153
127
  }
154
128
 
129
+ type SpinnerTheme = "default" | "dots" | "pulse" | "bars";
130
+ interface GradingOverlayProps {
131
+ visible: boolean;
132
+ bgColor?: string;
133
+ accentColor?: string;
134
+ text?: string;
135
+ aiText?: string;
136
+ spinnerTheme?: SpinnerTheme;
137
+ animationUrl?: string;
138
+ hasAiNodes?: boolean;
139
+ contained?: boolean;
140
+ }
141
+ type OverlayConfig = Pick<GradingOverlayProps, "bgColor" | "accentColor" | "text" | "spinnerTheme" | "animationUrl">;
142
+
143
+ /**
144
+ * Standalone, dependency-free i18n for the SDK shell.
145
+ *
146
+ * Replaces the web app's `useTranslations("learner.taking")` so the shell can
147
+ * be rendered in any React environment (Vite, CRA, Astro, UMD CDN, mobile
148
+ * WebView). Locale is passed as a prop — there is no React context to set up.
149
+ *
150
+ * Strings mirror `packages/i18n/messages/{en,fr,ar}.json` under `learner.taking.*`.
151
+ * Keep in sync if those copies are edited.
152
+ */
153
+ type ShellLocale = "en" | "fr" | "ar";
154
+
155
+ /**
156
+ * Public types for the Edpire Embeddable JS SDK.
157
+ */
158
+
159
+ type NodeFeedbackStatus = "correct" | "partial" | "incorrect" | "awaiting_review";
160
+ interface EmbedResult {
161
+ submission_id: string;
162
+ score: number;
163
+ max_score: number;
164
+ percentage: number;
165
+ passed: boolean;
166
+ passing_score_percent: number;
167
+ attempt_number: number;
168
+ /** True when the submission contains open-response nodes still pending teacher review. */
169
+ awaiting_manual_grading?: boolean;
170
+ exercise_results: Array<{
171
+ exercise_id: string;
172
+ total_score: number;
173
+ max_score: number;
174
+ question_results: Array<{
175
+ question_id: string;
176
+ score: number;
177
+ correct: boolean;
178
+ points: number;
179
+ }>;
180
+ }>;
181
+ exercise_feedback: Array<{
182
+ exercise_id: string;
183
+ questions: Array<{
184
+ question_id: string;
185
+ node_results: Array<{
186
+ node_id: string;
187
+ status: NodeFeedbackStatus;
188
+ score: number;
189
+ max_score: number;
190
+ feedback?: string;
191
+ display_answer?: string;
192
+ detail?: {
193
+ type: "choiceSet";
194
+ correctChoiceIds: string[];
195
+ } | {
196
+ type: "matchingSet";
197
+ pairFeedback: Array<{
198
+ leftId: string;
199
+ rightId: string;
200
+ correct: boolean;
201
+ }>;
202
+ correctPairings: Array<{
203
+ leftId: string;
204
+ rightId: string;
205
+ }>;
206
+ };
207
+ }>;
208
+ }>;
209
+ }>;
210
+ }
211
+ interface EmbedError {
212
+ code: "TOKEN_INVALID" | "TOKEN_EXPIRED" | "TOKEN_USED" | "ORIGIN_NOT_ALLOWED" | "ASSESSMENT_NOT_FOUND" | "MAX_ATTEMPTS_REACHED" | "NETWORK_ERROR" | "UNKNOWN";
213
+ message: string;
214
+ }
215
+
216
+ interface EdpireAssessmentPlayerProps {
217
+ /**
218
+ * URL of YOUR server endpoint that returns `{ token }`.
219
+ *
220
+ * The component POSTs `{ assessmentId, ...tokenBody }` here and uses the
221
+ * returned `token` to mount the player. Your endpoint should resolve the
222
+ * learner from your session — never from the request body.
223
+ *
224
+ * Pair with `createEdpireTokenHandler()` from `@edpire/sdk/client` to build
225
+ * the endpoint in one line.
226
+ *
227
+ * @example "/api/edpire/token"
228
+ */
229
+ tokenEndpoint: string;
230
+ /** Assessment UUID to embed. Sent to `tokenEndpoint` in the POST body. */
231
+ assessmentId: string;
232
+ /**
233
+ * Extra body fields merged into the POST to `tokenEndpoint`.
234
+ * Useful for passing context your server needs beyond `assessmentId`
235
+ * (e.g. a course ID for allow-list validation).
236
+ */
237
+ tokenBody?: Record<string, unknown>;
238
+ /** Base URL of the Edpire instance. Defaults to `"https://edpire.com"`. */
239
+ baseUrl?: string;
240
+ /** UI language. Defaults to `"en"`. RTL layout is applied automatically for `"ar"`. */
241
+ locale?: ShellLocale;
242
+ /** Branding overrides. Org branding loads from Edpire automatically; pass this to override (white-labelling). */
243
+ branding?: TakeBranding;
244
+ /**
245
+ * When set, the post-submit "View Full Report" button redirects here with
246
+ * `?submission_id=...&score=...&max_score=...` appended. Omit to hide the button.
247
+ */
248
+ returnUrl?: string;
249
+ /** Custom label for the post-submit report/redirect button. */
250
+ reportLabel?: string;
251
+ /** Called when the learner clicks Back (shown only before submission). */
252
+ onBack?: () => void;
253
+ /** Custom label for the back button. */
254
+ backLabel?: string;
255
+ /** Customise the grading overlay (spinner theme, animation, colors). */
256
+ overlayConfig?: OverlayConfig;
257
+ /**
258
+ * Media upload/recording handler.
259
+ *
260
+ * **Required** if the assessment contains OpenResponse questions with
261
+ * file-upload or audio/video recording modes. Without it those questions
262
+ * will not function correctly.
263
+ *
264
+ * @example
265
+ * ```typescript
266
+ * mediaHandler: {
267
+ * upload: async (file, { onProgress }) => {
268
+ * const form = new FormData()
269
+ * form.append("file", file)
270
+ * const res = await fetch("/api/upload", { method: "POST", body: form })
271
+ * const { url } = await res.json()
272
+ * return { url }
273
+ * },
274
+ * }
275
+ * ```
276
+ */
277
+ mediaHandler?: QuestionRuntimeProps["mediaHandler"];
278
+ /** Called when the learner successfully submits the assessment. */
279
+ onComplete?: (result: EmbedResult) => void;
280
+ /**
281
+ * Called when a non-recoverable error occurs (token fetch failure, invalid
282
+ * token, origin not allowed, etc.).
283
+ */
284
+ onError?: (error: EmbedError) => void;
285
+ /**
286
+ * CSS class name for the container `<div>`. Use this to control the player size.
287
+ *
288
+ * The player fills its container — you own the outer dimensions.
289
+ *
290
+ * @example "h-screen" // full viewport height
291
+ * @example "h-[600px] w-full" // fixed height
292
+ */
293
+ className?: string;
294
+ /**
295
+ * Inline style for the container `<div>`.
296
+ *
297
+ * When `className` is not set, defaults to `{ width: "100%", height: "100%" }`.
298
+ * Provide this (or `className`) to size the player — a zero-height container
299
+ * will collapse the player.
300
+ */
301
+ style?: React.CSSProperties;
302
+ }
303
+ /**
304
+ * Drop-in React component for the Edpire Embedded Player.
305
+ *
306
+ * Handles token fetching from your server, player mounting/unmounting, and
307
+ * React StrictMode double-invoke cleanup — the plumbing you'd otherwise write
308
+ * by hand with `useRef` + `useEffect`.
309
+ *
310
+ * The player fills its container: size it via `className` or `style`.
311
+ *
312
+ * @example
313
+ * ```tsx
314
+ * import { EdpireAssessmentPlayer } from "@edpire/sdk/react"
315
+ *
316
+ * function AssessmentPage({ assessmentId }: { assessmentId: string }) {
317
+ * return (
318
+ * <EdpireAssessmentPlayer
319
+ * tokenEndpoint="/api/edpire/token"
320
+ * assessmentId={assessmentId}
321
+ * onComplete={(r) => console.log("Score:", r.score, "/", r.max_score)}
322
+ * onError={(e) => console.error(e.code, e.message)}
323
+ * className="h-screen"
324
+ * />
325
+ * )
326
+ * }
327
+ * ```
328
+ */
329
+ declare function EdpireAssessmentPlayer({ tokenEndpoint, assessmentId, tokenBody, className, style, onComplete, onError, ...mountOptions }: EdpireAssessmentPlayerProps): react_jsx_runtime.JSX.Element;
330
+
155
331
  interface AssessmentShellProps {
156
332
  assessment: AssessmentContent;
157
333
  meta: {
@@ -197,4 +373,4 @@ interface AssessmentShellProps {
197
373
  }
198
374
  declare function AssessmentShell({ assessment, meta, locale, branding, timeLimitMinutes, startedAt, onSubmit, onViewReport, reportLabel, onBack, backLabel, allowReset, onReset, overlayConfig, contained, onClose, mediaHandler, fallbackLogoUrl, }: AssessmentShellProps): react_jsx_runtime.JSX.Element;
199
375
 
200
- export { AssessmentShell, type AssessmentShellProps, EdpireQuestion, type EdpireQuestionProps, type ExerciseFeedbackData, type NodeDetail, type NodeFeedback, type OverlayConfig, type QuestionFeedback, type ShellLocale, type SpinnerTheme, type SubmitResult, type TakeBranding };
376
+ export { AssessmentShell, type AssessmentShellProps, EdpireAssessmentPlayer, type EdpireAssessmentPlayerProps, EdpireQuestion, type EdpireQuestionProps, type ExerciseFeedbackData, type NodeDetail, type NodeFeedback, type OverlayConfig, type QuestionFeedback, type ShellLocale, type SpinnerTheme, type SubmitResult, type TakeBranding };