@pie-players/pie-section-player 0.3.53 → 0.3.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -196,16 +196,23 @@ Passage and item cards share a common header row
196
196
  - Title and toolbar are centered vertically by default. There is no prop or
197
197
  attribute for this — hosts needing a non-standard alignment should override
198
198
  the selector in their own stylesheet.
199
+ - Card corners default to `8px`. Hosts/themes can override the card radius via
200
+ `--pie-section-player-card-radius`.
199
201
  - The header fill is transparent by default. Hosts/themes opt into a color
200
202
  via the `--pie-section-player-card-header-background` CSS variable; the
201
203
  framework does not ship a brand palette.
204
+ - When a header fill is provided, header top corners default just inside the
205
+ card radius. Hosts/themes can override them independently via
206
+ `--pie-section-player-card-header-radius`.
202
207
 
203
208
  Example (host CSS):
204
209
 
205
210
  ```css
206
211
  pie-section-player-passage-card,
207
212
  pie-section-player-item-card {
213
+ --pie-section-player-card-radius: 8px;
208
214
  --pie-section-player-card-header-background: #c9e5e6;
215
+ --pie-section-player-card-header-radius: 7px;
209
216
  }
210
217
  ```
211
218
 
@@ -245,6 +252,70 @@ host.hooks = {
245
252
 
246
253
  Advanced runtime configuration is supplied through the `runtime` object. Set player config, tools, accessibility, coordinator, env, and `createSectionController` on `runtime.<key>`.
247
254
 
255
+ ### Backend delivery for embedded items
256
+
257
+ Hosts can configure item-player backend delivery once at the section-player
258
+ runtime level. Section-player derives a concrete `backend` prop for each
259
+ embedded item player before it renders the item. This is intended for hosts such
260
+ as Quiz Engine that need server-processed PIE models and server scoring without
261
+ querying every nested `<pie-item-player>`.
262
+
263
+ ```ts
264
+ import type {
265
+ SectionPlayerRuntimeConfig,
266
+ } from "@pie-players/pie-section-player";
267
+
268
+ const runtime: SectionPlayerRuntimeConfig = {
269
+ playerType: "iife",
270
+ env: {
271
+ mode: "gather",
272
+ role: "student",
273
+ },
274
+ player: {
275
+ backend: {
276
+ delivery: {
277
+ enabled: true,
278
+ baseUrl: bffUrl,
279
+ assignmentId: playerSessionId,
280
+ endpoints: {
281
+ load: "/api/player/load",
282
+ saveSession: "/api/player/save",
283
+ model: "/api/player/model",
284
+ score: "/api/player/score",
285
+ },
286
+ autosave: { enabled: true, debounceMs: 250 },
287
+ },
288
+ },
289
+ },
290
+ };
291
+
292
+ sectionPlayer.runtime = runtime;
293
+ ```
294
+
295
+ When `runtime.player.backend.delivery` is enabled, section-player treats
296
+ `itemId` and `sessionId` as per-item delivery identity. It derives them from
297
+ `canonicalItemId || item.id` and the item session before forwarding `backend` to
298
+ each embedded item player. Static delivery fields such as `baseUrl`, `auth`,
299
+ `endpoints`, `assignmentId`, and `autosave` are preserved. Use `assignmentId`
300
+ for shared attempt/player identity.
301
+
302
+ `runtime.player.resolveBackend` is a section-player-reserved key. It is called
303
+ with `{ itemId, canonicalItemId, item, itemIndex, itemSession, sectionId, env,
304
+ baseBackend }` and is stripped before props reach `<pie-item-player>`. Use it
305
+ only when the backend needs custom per-item identity mapping. The resolver
306
+ receives cloned backend objects, so per-item identity changes do not mutate the
307
+ shared runtime configuration or leak across items.
308
+
309
+ Section-player only derives the concrete `backend` prop. It does not call
310
+ `loadFromBackend()` on nested item players. Embedded `<pie-item-player>` loads
311
+ automatically when its derived `backend.delivery` config has a load signature,
312
+ so every mounted item player issues one backend load for its own item. Passage
313
+ players do not receive item delivery backend config, but shared non-delivery
314
+ backend config is preserved.
315
+
316
+ This backend delivery config is separate from the element-loader backend used
317
+ for IIFE/ESM bundle preloading.
318
+
248
319
  ### Host-owned focus
249
320
 
250
321
  Section-player does not move focus on behalf of host-level affordances such
@@ -0,0 +1,32 @@
1
+ import { BackendConfig } from '@pie-players/pie-item-player';
2
+ import { PlayerOverrides, RuntimeConfig } from '@pie-players/pie-assessment-toolkit/runtime/internal';
3
+ import { ItemEntity } from '@pie-players/pie-players-shared/types';
4
+ export type SectionPlayerBackendResolverContext = {
5
+ itemId: string;
6
+ canonicalItemId: string;
7
+ item: ItemEntity;
8
+ itemIndex: number;
9
+ itemSession?: Record<string, unknown>;
10
+ sectionId?: string;
11
+ env: Record<string, unknown>;
12
+ baseBackend: BackendConfig;
13
+ };
14
+ export type SectionPlayerBackendResolver = (context: SectionPlayerBackendResolverContext, baseBackend: BackendConfig) => BackendConfig | null | undefined;
15
+ export type SectionPlayerRuntimePlayerConfig = Omit<PlayerOverrides, "backend" | "resolveBackend"> & {
16
+ backend?: BackendConfig | null;
17
+ resolveBackend?: SectionPlayerBackendResolver;
18
+ };
19
+ export type SectionPlayerRuntimeConfig = Omit<RuntimeConfig, "player"> & {
20
+ player?: SectionPlayerRuntimePlayerConfig | null;
21
+ };
22
+ export type ResolveItemPlayerBackendPropsArgs = {
23
+ resolvedPlayerProps: Record<string, unknown>;
24
+ item: ItemEntity;
25
+ canonicalItemId: string;
26
+ itemSession?: Record<string, unknown>;
27
+ itemIndex?: number;
28
+ sectionId?: string;
29
+ env: Record<string, unknown>;
30
+ };
31
+ export declare function resolveItemPlayerPropsWithBackend(args: ResolveItemPlayerBackendPropsArgs): Record<string, unknown>;
32
+ export declare function stripItemDeliveryBackendProps(resolvedPlayerProps: Record<string, unknown>): Record<string, unknown>;
@@ -22,6 +22,13 @@ export declare function resolvePlayerRuntime(args: {
22
22
  [x: string]: unknown;
23
23
  };
24
24
  loaderConfig?: import('@pie-players/pie-players-shared').LoaderConfig;
25
+ hosted: boolean;
26
+ } | {
27
+ loaderOptions: {
28
+ [x: string]: unknown;
29
+ };
30
+ loaderConfig?: import('@pie-players/pie-players-shared').LoaderConfig;
31
+ hosted?: undefined;
25
32
  };
26
33
  resolvedPlayerEnv: Record<string, unknown>;
27
34
  strategy: import('@pie-players/pie-players-shared').ItemPlayerStrategy;
@@ -55,6 +62,13 @@ export declare function resolveSectionPlayerRuntimeState(args: RuntimeInputs): {
55
62
  [x: string]: unknown;
56
63
  };
57
64
  loaderConfig?: import('@pie-players/pie-players-shared').LoaderConfig;
65
+ hosted: boolean;
66
+ } | {
67
+ loaderOptions: {
68
+ [x: string]: unknown;
69
+ };
70
+ loaderConfig?: import('@pie-players/pie-players-shared').LoaderConfig;
71
+ hosted?: undefined;
58
72
  };
59
73
  resolvedPlayerEnv: Record<string, unknown>;
60
74
  strategy: import('@pie-players/pie-players-shared').ItemPlayerStrategy;
@@ -25,6 +25,7 @@ export declare function getItemPlayerParams(args: {
25
25
  resolvedPlayerAttributes: Record<string, string>;
26
26
  resolvedPlayerProps: Record<string, unknown>;
27
27
  playerStrategy: string;
28
+ itemIndex?: number;
28
29
  }): PlayerElementParams;
29
30
  export declare function getCanonicalItemId(args: {
30
31
  compositionModel: SectionCompositionModel;
@@ -7,3 +7,4 @@ export type { ReadinessPolicyAdapter, SectionPlayerPolicies, SectionPlayerReadin
7
7
  export { DEFAULT_SECTION_PLAYER_POLICIES, isPreloadEnabled, isTelemetryEnabled, } from './policies/index.js';
8
8
  export type { SectionPlayerCardTitleContext, SectionPlayerCardTitleFormatter, SectionPlayerItemTitleContext, SectionPlayerPassageTitleContext, } from './contracts/card-title-formatters.js';
9
9
  export type { SectionPlayerHostHooks } from './contracts/host-hooks.js';
10
+ export type { SectionPlayerBackendResolver, SectionPlayerBackendResolverContext, SectionPlayerRuntimeConfig, SectionPlayerRuntimePlayerConfig, } from './components/shared/section-player-backend-delivery.js';