@pie-players/pie-players-shared 0.3.74 → 1.0.0-beta.0
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 +88 -75
- package/dist/components/vendor/nds/README.md +4 -5
- package/dist/config/profile.d.ts +1 -1
- package/dist/config/profile.js +1 -1
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/language-tags.d.ts +9 -1
- package/dist/i18n/language-tags.js +11 -1
- package/dist/i18n/messages/en-US.d.ts +33 -28
- package/dist/i18n/messages/en-US.js +34 -29
- package/dist/i18n/messages/nl-NL.d.ts +33 -28
- package/dist/i18n/messages/nl-NL.js +34 -29
- package/dist/i18n/provider.d.ts +14 -7
- package/dist/i18n/provider.js +26 -29
- package/dist/i18n/types.d.ts +4 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/instrumentation/providers/BaseInstrumentationProvider.js +0 -14
- package/dist/loader-config.d.ts +0 -2
- package/dist/loader-config.js +0 -2
- package/dist/loaders/element-loader.js +13 -6
- package/dist/loaders/esm-adapter.d.ts +11 -0
- package/dist/loaders/esm-adapter.js +74 -45
- package/dist/loaders/iife-adapter.d.ts +3 -3
- package/dist/loaders/iife-adapter.js +36 -35
- package/dist/loaders/index.d.ts +4 -2
- package/dist/loaders/index.js +2 -1
- package/dist/loaders/mathjax-events.d.ts +22 -0
- package/dist/loaders/mathjax-events.js +65 -0
- package/dist/loaders/preloaded-registration.d.ts +18 -2
- package/dist/loaders/preloaded-registration.js +14 -2
- package/dist/media/index.d.ts +4 -6
- package/dist/media/index.js +6 -8
- package/dist/object/index.d.ts +8 -3
- package/dist/object/index.js +8 -6
- package/dist/pie/asset-handler.d.ts +0 -17
- package/dist/pie/asset-handler.js +1 -1
- package/dist/pie/authoring.js +5 -7
- package/dist/pie/elements-rendered.d.ts +23 -0
- package/dist/pie/elements-rendered.js +96 -0
- package/dist/pie/index.d.ts +4 -6
- package/dist/pie/index.js +4 -7
- package/dist/pie/initialization.d.ts +13 -14
- package/dist/pie/initialization.js +61 -75
- package/dist/pie/instrumentation-event-bridge.js +23 -1
- package/dist/pie/instrumentation-event-map.js +11 -18
- package/dist/pie/item-controller.js +4 -0
- package/dist/pie/item-session-contract.js +7 -9
- package/dist/pie/logger.d.ts +6 -0
- package/dist/pie/logger.js +10 -0
- package/dist/pie/math-assets.d.ts +48 -0
- package/dist/pie/math-assets.js +81 -0
- package/dist/pie/resource-monitor.d.ts +34 -32
- package/dist/pie/resource-monitor.js +152 -231
- package/dist/pie/scoring.d.ts +1 -6
- package/dist/pie/scoring.js +3 -8
- package/dist/pie/session-commit.js +1 -1
- package/dist/pie/stages.d.ts +11 -47
- package/dist/pie/stages.js +11 -47
- package/dist/pie/updates.js +5 -4
- package/dist/pie/utils.d.ts +0 -2
- package/dist/pie/utils.js +0 -2
- package/dist/security/sanitize-item-markup.d.ts +8 -4
- package/dist/security/sanitize-item-markup.js +52 -6
- package/dist/security/sanitize-svg-icon.js +2 -2
- package/dist/security/wrap-overwide-images.d.ts +1 -1
- package/dist/security/wrap-overwide-images.js +20 -1
- package/dist/security/wrap-overwide.d.ts +8 -0
- package/dist/security/wrap-overwide.js +47 -3
- package/dist/timed-media/media-element-source.js +1 -2
- package/dist/types/index.d.ts +88 -153
- package/dist/types/index.js +2 -2
- package/dist/ui/attribute-coercion.d.ts +5 -0
- package/dist/ui/attribute-coercion.js +6 -4
- package/dist/ui/content-styles.d.ts +6 -10
- package/dist/ui/content-styles.js +8 -13
- package/dist/ui/first-focusable.d.ts +0 -1
- package/dist/ui/first-focusable.js +0 -1
- package/dist/ui/focus-trap.js +2 -3
- package/dist/ui/scope-css.d.ts +23 -26
- package/dist/ui/scope-css.js +23 -26
- package/package.json +6 -4
- package/dist/loaders/mathjax-version-conflict.d.ts +0 -17
- package/dist/loaders/mathjax-version-conflict.js +0 -51
- package/dist/pie/stage-tracker.d.ts +0 -50
- package/dist/pie/stage-tracker.js +0 -105
package/dist/ui/scope-css.js
CHANGED
|
@@ -4,37 +4,34 @@
|
|
|
4
4
|
* external-style-urls="...">` or `itemConfig.resources.stylesheets[*].url`
|
|
5
5
|
* styles that player's subtree instead of the whole host document.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
7
|
+
* Walks the stylesheet brace-by-brace. Block at-rules that hold rules
|
|
8
|
+
* (`@media`, `@supports`, `@container`, `@layer`, `@scope`) keep their prelude
|
|
9
|
+
* and have their inner rules scoped, every other at-rule passes through, and a
|
|
10
|
+
* leading `:root`, `html` or `body` is replaced by the scope, since
|
|
11
|
+
* `.scope :root` can never match: `:root` is `<html>`, which is no descendant
|
|
12
|
+
* of the player. A regex prefixer fails on exactly these cases: it turned
|
|
13
|
+
* `@media screen { … }` into the invalid `.scope @media screen { … }`, which the
|
|
14
|
+
* browser drops with every rule inside, and corrupted `@font-face`,
|
|
15
|
+
* `@keyframes` and `:root` the same way.
|
|
15
16
|
*
|
|
16
|
-
* The QTI player's `scopeCssRules` (`pie-qti` -
|
|
17
|
-
* `packages/item-player/src/components/utils/stylesheetRender.ts`) is
|
|
18
|
-
* drop-in
|
|
19
|
-
*
|
|
20
|
-
* at
|
|
21
|
-
* rules are hoisted and applied unconditionally — a mobile-only rule then
|
|
22
|
-
* applies at every viewport width, which is a subtler failure than dropping it.
|
|
17
|
+
* The `:root` handling follows the QTI player's `scopeCssRules` (`pie-qti` -
|
|
18
|
+
* `packages/item-player/src/components/utils/stylesheetRender.ts`), which is no
|
|
19
|
+
* drop-in: it excludes `@` from its selector pattern without understanding
|
|
20
|
+
* at-rules, so `@media` and `@supports` lose their condition and their rules
|
|
21
|
+
* apply at every viewport width.
|
|
23
22
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* runs in the delivery path, and scoping needs to know about rule boundaries
|
|
28
|
-
* only — not about property grammar.
|
|
23
|
+
* No CSS parser: `@pie-players/pie-item-player` ships with two workspace
|
|
24
|
+
* dependencies, this runs in the delivery path, and scoping needs rule
|
|
25
|
+
* boundaries only.
|
|
29
26
|
*
|
|
30
|
-
* Known limits
|
|
27
|
+
* Known limits:
|
|
31
28
|
*
|
|
32
|
-
* - `@import` is passed through untouched
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
29
|
+
* - `@import` is passed through untouched. It pulls in an unscoped stylesheet,
|
|
30
|
+
* so it defeats scoping, but blocking it is a security policy decision and
|
|
31
|
+
* not this function's job. Callers gate stylesheet URLs with
|
|
32
|
+
* `validateExternalStyleUrl` before fetching.
|
|
36
33
|
* - Declaration blocks are emitted verbatim, so `url(...)` references are left
|
|
37
|
-
* as authored and resolve against the stylesheet's own URL
|
|
34
|
+
* as authored and resolve against the stylesheet's own URL.
|
|
38
35
|
* - A style rule's block is never rewritten, which is also what native CSS
|
|
39
36
|
* nesting needs: nested selectors are relative to a parent that has already
|
|
40
37
|
* been scoped.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-players-shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared runtime + UI utilities for PIE players",
|
|
6
6
|
"license": "MIT",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"dist"
|
|
103
103
|
],
|
|
104
104
|
"dependencies": {
|
|
105
|
+
"@pie-element/shared-utils": "0.1.3",
|
|
105
106
|
"@pie-lib/math-rendering-module": "6.0.0",
|
|
106
107
|
"dompurify": "^3.4.16",
|
|
107
108
|
"semver": "^7.8.5"
|
|
@@ -109,9 +110,9 @@
|
|
|
109
110
|
"scripts": {
|
|
110
111
|
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && node scripts/bundle-vendored-modules.mjs && mkdir -p dist/components && cp -R src/components/vendor dist/components/vendor",
|
|
111
112
|
"dev": "tsc -p tsconfig.json --watch",
|
|
112
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
113
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json",
|
|
113
114
|
"lint": "biome lint .",
|
|
114
|
-
"check": "
|
|
115
|
+
"check": "svelte-check --tsconfig ./tsconfig.svelte-check.json",
|
|
115
116
|
"test": "bun test",
|
|
116
117
|
"check-i18n": "bun run src/i18n/scripts/check-coverage.ts",
|
|
117
118
|
"scan-hardcoded": "bun run src/i18n/scripts/scan-hardcoded.ts"
|
|
@@ -119,13 +120,14 @@
|
|
|
119
120
|
"devDependencies": {
|
|
120
121
|
"@biomejs/biome": "^2.5.15",
|
|
121
122
|
"@happy-dom/global-registrator": "^20.14.5",
|
|
122
|
-
"@pie-element/shared-math-rendering-mathjax": "0.1.
|
|
123
|
+
"@pie-element/shared-math-rendering-mathjax": "0.1.4",
|
|
123
124
|
"@playwright/test": "^1.63.0",
|
|
124
125
|
"@types/semver": "^7.8.0",
|
|
125
126
|
"es-module-shims": "^2.8.4",
|
|
126
127
|
"esbuild": "^0.28.2",
|
|
127
128
|
"glob": "^13.0.0",
|
|
128
129
|
"svelte": "^5.57.1",
|
|
130
|
+
"svelte-check": "^4.7.6",
|
|
129
131
|
"typescript": "^5.9.3"
|
|
130
132
|
},
|
|
131
133
|
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/players-shared#readme",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Forwards the MathJax version-conflict event to instrumentation.
|
|
3
|
-
*
|
|
4
|
-
* The MathJax 4 adapter that browser ESM elements render with dispatches
|
|
5
|
-
* `pie-mathjax-version-conflict` on `window`, once per condition per page, when
|
|
6
|
-
* MathJax 3 runs on the same page — an unsupported page, see
|
|
7
|
-
* docs/item-player/loading-strategies.md#one-mathjax-version-per-page. The
|
|
8
|
-
* event name is repeated here because players do not depend on the element
|
|
9
|
-
* packages.
|
|
10
|
-
*/
|
|
11
|
-
import type { InstrumentationProvider } from "../instrumentation/types.js";
|
|
12
|
-
export declare const MATHJAX_VERSION_CONFLICT_EVENT = "pie-mathjax-version-conflict";
|
|
13
|
-
/**
|
|
14
|
-
* Tracks each `pie-mathjax-version-conflict` event on `target` with the
|
|
15
|
-
* provider `getProvider` returns when it fires, once per provider.
|
|
16
|
-
*/
|
|
17
|
-
export declare function forwardMathjaxVersionConflicts(target: EventTarget, getProvider: () => InstrumentationProvider | undefined): void;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Forwards the MathJax version-conflict event to instrumentation.
|
|
3
|
-
*
|
|
4
|
-
* The MathJax 4 adapter that browser ESM elements render with dispatches
|
|
5
|
-
* `pie-mathjax-version-conflict` on `window`, once per condition per page, when
|
|
6
|
-
* MathJax 3 runs on the same page — an unsupported page, see
|
|
7
|
-
* docs/item-player/loading-strategies.md#one-mathjax-version-per-page. The
|
|
8
|
-
* event name is repeated here because players do not depend on the element
|
|
9
|
-
* packages.
|
|
10
|
-
*/
|
|
11
|
-
export const MATHJAX_VERSION_CONFLICT_EVENT = "pie-mathjax-version-conflict";
|
|
12
|
-
// Every ESM backend on a page listens, and each player bundle carries its own
|
|
13
|
-
// copy of this module, so the providers that tracked an event are kept on the
|
|
14
|
-
// page.
|
|
15
|
-
const TRACKED = Symbol.for("@pie-players/pie-players-shared/mathjax-version-conflict-tracked");
|
|
16
|
-
function providersThatTracked(event) {
|
|
17
|
-
const registry = globalThis;
|
|
18
|
-
registry[TRACKED] ??= new WeakMap();
|
|
19
|
-
let providers = registry[TRACKED].get(event);
|
|
20
|
-
if (!providers) {
|
|
21
|
-
providers = new WeakSet();
|
|
22
|
-
registry[TRACKED].set(event, providers);
|
|
23
|
-
}
|
|
24
|
-
return providers;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Tracks each `pie-mathjax-version-conflict` event on `target` with the
|
|
28
|
-
* provider `getProvider` returns when it fires, once per provider.
|
|
29
|
-
*/
|
|
30
|
-
export function forwardMathjaxVersionConflicts(target, getProvider) {
|
|
31
|
-
target.addEventListener(MATHJAX_VERSION_CONFLICT_EVENT, (event) => {
|
|
32
|
-
const provider = getProvider();
|
|
33
|
-
if (!provider)
|
|
34
|
-
return;
|
|
35
|
-
const tracked = providersThatTracked(event);
|
|
36
|
-
if (tracked.has(provider))
|
|
37
|
-
return;
|
|
38
|
-
tracked.add(provider);
|
|
39
|
-
const detail = event.detail;
|
|
40
|
-
const { condition, docsUrl } = (detail && typeof detail === "object" ? detail : {});
|
|
41
|
-
try {
|
|
42
|
-
provider.trackEvent(MATHJAX_VERSION_CONFLICT_EVENT, {
|
|
43
|
-
condition,
|
|
44
|
-
docsUrl,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
// Swallow: instrumentation must never break rendering.
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { type Stage, type StageChangeDetail, type StageSourceCe, type StageStatus } from "./stages.js";
|
|
2
|
-
/**
|
|
3
|
-
* Stage tracker primitive (M6).
|
|
4
|
-
*
|
|
5
|
-
* One tracker per CE instance per cohort. `enter(stage, status?)` is the
|
|
6
|
-
* only mutation; `reset()` rolls the cohort over (e.g. when
|
|
7
|
-
* `(sectionId, attemptId)` changes).
|
|
8
|
-
*
|
|
9
|
-
* The tracker enforces the locked invariants from
|
|
10
|
-
* `m6_ready_vocab_canonical_followup.plan.md` §3.1–§3.6:
|
|
11
|
-
* - Monotonic ordering across `STAGES`. Backward transitions inside one
|
|
12
|
-
* cohort are rejected (dev) / warned-once (prod) so subscribers never
|
|
13
|
-
* see a stage regress without an intervening `reset()`.
|
|
14
|
-
* - Per-CE applicability. The post-retro canonical list applies to
|
|
15
|
-
* every CE shape; the `applicableStages` indirection is kept so a
|
|
16
|
-
* future shape-specific stage can opt out without rewriting callers.
|
|
17
|
-
* Non-applicable stages auto-emit `status: "skipped"` when an
|
|
18
|
-
* applicable later stage is entered, so iteration order stays stable
|
|
19
|
-
* across CE shapes.
|
|
20
|
-
* - One source for every emit. The injected `emit(detail)` function
|
|
21
|
-
* drives DOM events, engine subscribers, and coordinator subscribers
|
|
22
|
-
* from the same call site so no surface drifts.
|
|
23
|
-
*
|
|
24
|
-
* Failure semantics intentionally piggyback on the M3 framework-error
|
|
25
|
-
* contract: `enter(stage, "failed")` records the position; the
|
|
26
|
-
* framework error records the cause.
|
|
27
|
-
*/
|
|
28
|
-
export type CreateStageTrackerOptions = {
|
|
29
|
-
sourceCe: string;
|
|
30
|
-
sourceCeShape: StageSourceCe;
|
|
31
|
-
runtimeId: string;
|
|
32
|
-
sectionId?: string;
|
|
33
|
-
attemptId?: string;
|
|
34
|
-
emit: (detail: StageChangeDetail) => void;
|
|
35
|
-
now?: () => string;
|
|
36
|
-
onUnexpectedTransition?: (info: {
|
|
37
|
-
from: Stage | null;
|
|
38
|
-
to: Stage;
|
|
39
|
-
reason: "backward" | "duplicate";
|
|
40
|
-
}) => void;
|
|
41
|
-
};
|
|
42
|
-
export type StageTracker = {
|
|
43
|
-
enter: (stage: Stage, status?: StageStatus) => void;
|
|
44
|
-
reset: (next?: {
|
|
45
|
-
sectionId?: string;
|
|
46
|
-
attemptId?: string;
|
|
47
|
-
}) => void;
|
|
48
|
-
getCurrent: () => Stage | null;
|
|
49
|
-
};
|
|
50
|
-
export declare function createStageTracker(opts: CreateStageTrackerOptions): StageTracker;
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { STAGES, applicableStages, stageOrdinal, } from "./stages.js";
|
|
2
|
-
let unexpectedTransitionWarned = false;
|
|
3
|
-
function defaultUnexpectedTransitionLogger(info) {
|
|
4
|
-
if (unexpectedTransitionWarned)
|
|
5
|
-
return;
|
|
6
|
-
unexpectedTransitionWarned = true;
|
|
7
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
8
|
-
console.warn(`[pie-stage-tracker] Unexpected ${info.reason} stage transition ` +
|
|
9
|
-
`from \`${info.from ?? "<none>"}\` to \`${info.to}\`. ` +
|
|
10
|
-
`Stage transitions are expected to be monotonic within a cohort; ` +
|
|
11
|
-
`call \`reset()\` when \`(sectionId, attemptId)\` changes.`);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export function createStageTracker(opts) {
|
|
15
|
-
const applicable = applicableStages(opts.sourceCeShape);
|
|
16
|
-
const applicableSet = new Set(applicable);
|
|
17
|
-
const now = opts.now ?? (() => new Date().toISOString());
|
|
18
|
-
const onUnexpected = opts.onUnexpectedTransition ?? defaultUnexpectedTransitionLogger;
|
|
19
|
-
let current = null;
|
|
20
|
-
let sectionId = opts.sectionId;
|
|
21
|
-
let attemptId = opts.attemptId;
|
|
22
|
-
const emitted = new Set();
|
|
23
|
-
function emitDetail(stage, status) {
|
|
24
|
-
opts.emit({
|
|
25
|
-
stage,
|
|
26
|
-
status,
|
|
27
|
-
runtimeId: opts.runtimeId,
|
|
28
|
-
sectionId,
|
|
29
|
-
attemptId,
|
|
30
|
-
timestamp: now(),
|
|
31
|
-
sourceCe: opts.sourceCe,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
function fillSkippedBefore(stage) {
|
|
35
|
-
const targetIdx = stageOrdinal(stage);
|
|
36
|
-
const startIdx = current === null ? 0 : stageOrdinal(current) + 1;
|
|
37
|
-
for (let idx = startIdx; idx < targetIdx; idx += 1) {
|
|
38
|
-
const skipCandidate = STAGES[idx];
|
|
39
|
-
if (applicableSet.has(skipCandidate))
|
|
40
|
-
continue;
|
|
41
|
-
if (emitted.has(skipCandidate))
|
|
42
|
-
continue;
|
|
43
|
-
emitted.add(skipCandidate);
|
|
44
|
-
emitDetail(skipCandidate, "skipped");
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function enter(stage, status = "entered") {
|
|
48
|
-
const nextOrdinal = stageOrdinal(stage);
|
|
49
|
-
const currentOrdinal = current === null ? -1 : stageOrdinal(current);
|
|
50
|
-
if (status === "entered") {
|
|
51
|
-
if (emitted.has(stage)) {
|
|
52
|
-
onUnexpected({ from: current, to: stage, reason: "duplicate" });
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (nextOrdinal < currentOrdinal) {
|
|
56
|
-
onUnexpected({ from: current, to: stage, reason: "backward" });
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (!applicableSet.has(stage)) {
|
|
60
|
-
// A non-applicable stage entered with `entered` is a programming
|
|
61
|
-
// error: the tracker auto-skips it when a later stage enters.
|
|
62
|
-
// Treat it as a `skipped` emission and continue.
|
|
63
|
-
if (emitted.has(stage))
|
|
64
|
-
return;
|
|
65
|
-
emitted.add(stage);
|
|
66
|
-
emitDetail(stage, "skipped");
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
fillSkippedBefore(stage);
|
|
70
|
-
emitted.add(stage);
|
|
71
|
-
current = stage;
|
|
72
|
-
emitDetail(stage, "entered");
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// `status === "failed"` records position; do not gate on monotonic
|
|
76
|
-
// ordering — failure can happen during any transition. Mark the stage
|
|
77
|
-
// as emitted so a subsequent `entered` for the same stage warns as a
|
|
78
|
-
// duplicate; downstream recovery should call `reset()` first.
|
|
79
|
-
if (status === "failed") {
|
|
80
|
-
fillSkippedBefore(stage);
|
|
81
|
-
emitted.add(stage);
|
|
82
|
-
current = stage;
|
|
83
|
-
emitDetail(stage, "failed");
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
// `status === "skipped"` is reserved for the auto-fill path; explicit
|
|
87
|
-
// callers shouldn't pass it. Accept it idempotently for robustness.
|
|
88
|
-
if (emitted.has(stage))
|
|
89
|
-
return;
|
|
90
|
-
emitted.add(stage);
|
|
91
|
-
emitDetail(stage, "skipped");
|
|
92
|
-
}
|
|
93
|
-
function reset(next) {
|
|
94
|
-
current = null;
|
|
95
|
-
emitted.clear();
|
|
96
|
-
if (next) {
|
|
97
|
-
sectionId = next.sectionId;
|
|
98
|
-
attemptId = next.attemptId;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function getCurrent() {
|
|
102
|
-
return current;
|
|
103
|
-
}
|
|
104
|
-
return { enter, reset, getCurrent };
|
|
105
|
-
}
|