@qti-components/base 1.4.3 → 1.5.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.
@@ -1,7 +1,43 @@
1
+ /**
2
+ * A validated deterministic shuffle seed.
3
+ *
4
+ * Branded so that only values verified through {@link isSeed} (or constructed via
5
+ * {@link asSeed}) can be assigned where a seed is expected. This prevents arbitrary
6
+ * strings from silently being used as a seed.
7
+ *
8
+ * A usable seed is a non-empty string of letters, digits and hyphens (e.g. a GUID
9
+ * "N" format like `8f14e45fceea167a5a36dedd4bea2543`, or a readable label like
10
+ * `delivery-2026-06-05`). Whitespace and other characters are rejected.
11
+ */
12
+ export type Seed = string & {
13
+ readonly __seedBrand: 'Seed';
14
+ };
15
+ /**
16
+ * Runtime type guard that narrows an unknown value to a {@link Seed}.
17
+ * Use this at boundaries (e.g. values coming from XML, a host application or a
18
+ * backend) before treating a string as a seed.
19
+ */
20
+ export declare const isSeed: (value: unknown) => value is Seed;
21
+ /**
22
+ * Validates and brands a value as a {@link Seed}, returning `undefined` when the
23
+ * value is missing or not in a usable seed format.
24
+ */
25
+ export declare const asSeed: (value: unknown) => Seed | undefined;
1
26
  export type QtiContextType = {
2
27
  testIdentifier: string;
3
28
  candidateIdentifier: string;
4
29
  environmentIdentifier: string;
30
+ /**
31
+ * Optional deterministic seed for shuffling.
32
+ *
33
+ * When set, it is used to reproduce a stable shuffle order across reloads/restarts:
34
+ * - test ordering in `test-container` (`<qti-ordering shuffle="true">`),
35
+ * - seeded item interaction shuffling in `item-container` and during test navigation.
36
+ *
37
+ * Typically generated once per session by the host/backend and passed in via
38
+ * `QTI_CONTEXT`. When omitted, each item falls back to its own URI-derived seed.
39
+ */
40
+ seed?: Seed;
5
41
  [key: string]: string | string[];
6
42
  };
7
43
  export interface QtiContext {
@@ -1,3 +1,16 @@
1
1
  import { createContext } from '@lit/context';
2
+ /** Format a value must match to be usable as a {@link Seed}. */
3
+ const SEED_PATTERN = /^[A-Za-z0-9-]+$/;
4
+ /**
5
+ * Runtime type guard that narrows an unknown value to a {@link Seed}.
6
+ * Use this at boundaries (e.g. values coming from XML, a host application or a
7
+ * backend) before treating a string as a seed.
8
+ */
9
+ export const isSeed = (value) => typeof value === 'string' && SEED_PATTERN.test(value);
10
+ /**
11
+ * Validates and brands a value as a {@link Seed}, returning `undefined` when the
12
+ * value is missing or not in a usable seed format.
13
+ */
14
+ export const asSeed = (value) => (isSeed(value) ? value : undefined);
2
15
  export const qtiContext = createContext(Symbol('qtiContext'));
3
16
  //# sourceMappingURL=qti.context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qti.context.js","sourceRoot":"","sources":["../../src/context/qti.context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAa7C,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAuB,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC","sourcesContent":["import { createContext } from '@lit/context';\n\nexport type QtiContextType = {\n testIdentifier: string;\n candidateIdentifier: string;\n environmentIdentifier: string;\n [key: string]: string | string[]; // Allow for additional context variables\n};\n\nexport interface QtiContext {\n QTI_CONTEXT: QtiContextType;\n}\n\nexport const qtiContext = createContext<Readonly<QtiContext>>(Symbol('qtiContext'));\n"]}
1
+ {"version":3,"file":"qti.context.js","sourceRoot":"","sources":["../../src/context/qti.context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAe7C,gEAAgE;AAChE,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAiB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAE/G;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAoB,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAwBhG,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAuB,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC","sourcesContent":["import { createContext } from '@lit/context';\n\n/**\n * A validated deterministic shuffle seed.\n *\n * Branded so that only values verified through {@link isSeed} (or constructed via\n * {@link asSeed}) can be assigned where a seed is expected. This prevents arbitrary\n * strings from silently being used as a seed.\n *\n * A usable seed is a non-empty string of letters, digits and hyphens (e.g. a GUID\n * \"N\" format like `8f14e45fceea167a5a36dedd4bea2543`, or a readable label like\n * `delivery-2026-06-05`). Whitespace and other characters are rejected.\n */\nexport type Seed = string & { readonly __seedBrand: 'Seed' };\n\n/** Format a value must match to be usable as a {@link Seed}. */\nconst SEED_PATTERN = /^[A-Za-z0-9-]+$/;\n\n/**\n * Runtime type guard that narrows an unknown value to a {@link Seed}.\n * Use this at boundaries (e.g. values coming from XML, a host application or a\n * backend) before treating a string as a seed.\n */\nexport const isSeed = (value: unknown): value is Seed => typeof value === 'string' && SEED_PATTERN.test(value);\n\n/**\n * Validates and brands a value as a {@link Seed}, returning `undefined` when the\n * value is missing or not in a usable seed format.\n */\nexport const asSeed = (value: unknown): Seed | undefined => (isSeed(value) ? value : undefined);\n\nexport type QtiContextType = {\n testIdentifier: string;\n candidateIdentifier: string;\n environmentIdentifier: string;\n /**\n * Optional deterministic seed for shuffling.\n *\n * When set, it is used to reproduce a stable shuffle order across reloads/restarts:\n * - test ordering in `test-container` (`<qti-ordering shuffle=\"true\">`),\n * - seeded item interaction shuffling in `item-container` and during test navigation.\n *\n * Typically generated once per session by the host/backend and passed in via\n * `QTI_CONTEXT`. When omitted, each item falls back to its own URI-derived seed.\n */\n seed?: Seed;\n [key: string]: string | string[]; // Allow for additional context variables\n};\n\nexport interface QtiContext {\n QTI_CONTEXT: QtiContextType;\n}\n\nexport const qtiContext = createContext<Readonly<QtiContext>>(Symbol('qtiContext'));\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@qti-components/base",
3
3
  "description": "QTI shared utilities",
4
- "version": "1.4.3",
4
+ "version": "1.5.1",
5
5
  "author": "",
6
6
  "dependencies": {
7
7
  "@qti-components/utilities": "^1.3.3"