@pie-players/pie-section-player-tools-session-debugger 0.3.43 → 0.3.45
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 +26 -0
- package/dist/index.d.ts +0 -1
- package/dist/section-player-tools-session-debugger.js +1540 -2151
- package/dist/vite.config.d.ts +0 -1
- package/package.json +4 -7
- package/SectionSessionPanel.svelte +0 -370
- package/dist/index.d.ts.map +0 -1
- package/dist/vite.config.d.ts.map +0 -1
package/dist/vite.config.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-section-player-tools-session-debugger",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.45",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Session debugger panel for PIE section-player flows",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"debugger",
|
|
20
20
|
"web-component"
|
|
21
21
|
],
|
|
22
|
-
"svelte": "./SectionSessionPanel.svelte",
|
|
23
22
|
"main": "./dist/section-player-tools-session-debugger.js",
|
|
24
23
|
"module": "./dist/section-player-tools-session-debugger.js",
|
|
25
24
|
"unpkg": "./dist/section-player-tools-session-debugger.js",
|
|
@@ -27,19 +26,17 @@
|
|
|
27
26
|
"exports": {
|
|
28
27
|
".": {
|
|
29
28
|
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/section-player-tools-session-debugger.js"
|
|
31
|
-
"svelte": "./SectionSessionPanel.svelte"
|
|
29
|
+
"import": "./dist/section-player-tools-session-debugger.js"
|
|
32
30
|
}
|
|
33
31
|
},
|
|
34
32
|
"files": [
|
|
35
33
|
"dist",
|
|
36
|
-
"SectionSessionPanel.svelte",
|
|
37
34
|
"package.json"
|
|
38
35
|
],
|
|
39
36
|
"license": "MIT",
|
|
40
37
|
"dependencies": {
|
|
41
|
-
"@pie-players/pie-section-player-tools-shared": "0.3.
|
|
42
|
-
"@pie-players/pie-theme": "0.3.
|
|
38
|
+
"@pie-players/pie-section-player-tools-shared": "0.3.45",
|
|
39
|
+
"@pie-players/pie-theme": "0.3.45"
|
|
43
40
|
},
|
|
44
41
|
"types": "./dist/index.d.ts",
|
|
45
42
|
"scripts": {
|
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
<svelte:options
|
|
2
|
-
customElement={{
|
|
3
|
-
tag: 'pie-section-player-tools-session-debugger',
|
|
4
|
-
shadow: 'none',
|
|
5
|
-
props: {
|
|
6
|
-
sectionId: { type: 'String', attribute: 'section-id' },
|
|
7
|
-
attemptId: { type: 'String', attribute: 'attempt-id' },
|
|
8
|
-
toolkitCoordinator: { type: 'Object', attribute: 'toolkit-coordinator' }
|
|
9
|
-
}
|
|
10
|
-
}}
|
|
11
|
-
/>
|
|
12
|
-
|
|
13
|
-
<script lang="ts">
|
|
14
|
-
import '@pie-players/pie-theme/components.css';
|
|
15
|
-
import SharedFloatingPanel from '@pie-players/pie-section-player-tools-shared/SharedFloatingPanel.svelte';
|
|
16
|
-
import {
|
|
17
|
-
getSectionControllerFromCoordinator,
|
|
18
|
-
isMatchingSectionControllerLifecycleEvent
|
|
19
|
-
} from '@pie-players/pie-section-player-tools-shared';
|
|
20
|
-
import { createEventDispatcher } from 'svelte';
|
|
21
|
-
const dispatch = createEventDispatcher<{ close: undefined }>();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
type SessionPanelSnapshot = {
|
|
25
|
-
currentItemIndex: number | null;
|
|
26
|
-
currentItemId: string | null;
|
|
27
|
-
visitedItemIdentifiers: string[];
|
|
28
|
-
loadingComplete: boolean;
|
|
29
|
-
totalRegistered: number;
|
|
30
|
-
totalLoaded: number;
|
|
31
|
-
itemsComplete: boolean;
|
|
32
|
-
completedCount: number;
|
|
33
|
-
totalItems: number;
|
|
34
|
-
updatedAt: number | null;
|
|
35
|
-
lastChangedItemId: string | null;
|
|
36
|
-
itemSessions: Record<string, unknown>;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
type SectionAttemptSliceLike = {
|
|
40
|
-
currentItemIndex?: number;
|
|
41
|
-
currentItemId?: string;
|
|
42
|
-
visitedItemIdentifiers?: string[];
|
|
43
|
-
itemSessions?: Record<string, unknown>;
|
|
44
|
-
loadingComplete?: boolean;
|
|
45
|
-
totalRegistered?: number;
|
|
46
|
-
totalLoaded?: number;
|
|
47
|
-
itemsComplete?: boolean;
|
|
48
|
-
completedCount?: number;
|
|
49
|
-
totalItems?: number;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type SectionSessionStateLike = {
|
|
53
|
-
itemSessions?: Record<string, unknown>;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
type SectionControllerLike = {
|
|
57
|
-
getRuntimeState?: () => SectionAttemptSliceLike | null;
|
|
58
|
-
getSession?: () => SectionSessionStateLike | null;
|
|
59
|
-
subscribe?: (listener: (event: { itemId?: string; timestamp?: number }) => void) => () => void;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
type ToolkitCoordinatorLike = {
|
|
63
|
-
getSectionController?: (args: { sectionId: string; attemptId?: string }) => SectionControllerLike | undefined;
|
|
64
|
-
// Phase D (>=0.3.35): subscribe* helpers follow the toolkit's
|
|
65
|
-
// active section cohort automatically and do not accept
|
|
66
|
-
// sectionId / attemptId arguments. The session panel keeps
|
|
67
|
-
// `sectionId` + `attemptId` in `subscriptionTarget` purely to
|
|
68
|
-
// gate same-target re-subscribe and to drive `getSectionController`.
|
|
69
|
-
subscribeItemEvents?: (args: {
|
|
70
|
-
listener: (event: { itemId?: string; timestamp?: number }) => void;
|
|
71
|
-
}) => () => void;
|
|
72
|
-
subscribeSectionLifecycleEvents?: (args: {
|
|
73
|
-
listener: (event: { itemId?: string; timestamp?: number }) => void;
|
|
74
|
-
}) => () => void;
|
|
75
|
-
onSectionControllerLifecycle?: (
|
|
76
|
-
listener: (event: { type: 'ready' | 'disposed'; key?: { sectionId?: string; attemptId?: string } }) => void
|
|
77
|
-
) => () => void;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
let {
|
|
81
|
-
toolkitCoordinator = null,
|
|
82
|
-
sectionId = '',
|
|
83
|
-
attemptId = undefined
|
|
84
|
-
}: {
|
|
85
|
-
toolkitCoordinator?: ToolkitCoordinatorLike | null;
|
|
86
|
-
sectionId: string;
|
|
87
|
-
attemptId?: string;
|
|
88
|
-
} = $props();
|
|
89
|
-
|
|
90
|
-
let sessionPanelSnapshot = $state<SessionPanelSnapshot>({
|
|
91
|
-
currentItemIndex: null,
|
|
92
|
-
currentItemId: null,
|
|
93
|
-
visitedItemIdentifiers: [],
|
|
94
|
-
loadingComplete: false,
|
|
95
|
-
totalRegistered: 0,
|
|
96
|
-
totalLoaded: 0,
|
|
97
|
-
itemsComplete: false,
|
|
98
|
-
completedCount: 0,
|
|
99
|
-
totalItems: 0,
|
|
100
|
-
updatedAt: null,
|
|
101
|
-
lastChangedItemId: null,
|
|
102
|
-
itemSessions: {}
|
|
103
|
-
});
|
|
104
|
-
let unsubscribeController: (() => void) | null = null;
|
|
105
|
-
let unsubscribeLifecycle: (() => void) | null = null;
|
|
106
|
-
let controllerAvailable = $state(false);
|
|
107
|
-
let resubscribeQueued = false;
|
|
108
|
-
const subscriptionTarget: {
|
|
109
|
-
controller: SectionControllerLike | null;
|
|
110
|
-
sectionId: string;
|
|
111
|
-
attemptId?: string;
|
|
112
|
-
} = {
|
|
113
|
-
controller: null,
|
|
114
|
-
sectionId: '',
|
|
115
|
-
attemptId: undefined
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
function cloneSessionSnapshot<T>(value: T): T {
|
|
119
|
-
try {
|
|
120
|
-
return structuredClone(value);
|
|
121
|
-
} catch {
|
|
122
|
-
try {
|
|
123
|
-
return JSON.parse(JSON.stringify(value)) as T;
|
|
124
|
-
} catch {
|
|
125
|
-
// Keep debugger resilient if a session payload contains non-serializable values.
|
|
126
|
-
return value;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function getController(): SectionControllerLike | undefined {
|
|
132
|
-
return (
|
|
133
|
-
getSectionControllerFromCoordinator(
|
|
134
|
-
toolkitCoordinator,
|
|
135
|
-
sectionId,
|
|
136
|
-
attemptId
|
|
137
|
-
) || undefined
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function refreshFromController(
|
|
142
|
-
meta?: { itemId?: string; updatedAt?: number },
|
|
143
|
-
controllerOverride?: SectionControllerLike | null
|
|
144
|
-
) {
|
|
145
|
-
const controller = controllerOverride || getController();
|
|
146
|
-
const sectionSlice = controller?.getRuntimeState?.() || null;
|
|
147
|
-
const persistedSlice = controller?.getSession?.() || null;
|
|
148
|
-
controllerAvailable = Boolean(controller);
|
|
149
|
-
sessionPanelSnapshot = {
|
|
150
|
-
currentItemIndex:
|
|
151
|
-
typeof sectionSlice?.currentItemIndex === 'number' && sectionSlice.currentItemIndex >= 0
|
|
152
|
-
? sectionSlice.currentItemIndex
|
|
153
|
-
: null,
|
|
154
|
-
currentItemId:
|
|
155
|
-
typeof sectionSlice?.currentItemId === 'string' && sectionSlice.currentItemId
|
|
156
|
-
? sectionSlice.currentItemId
|
|
157
|
-
: null,
|
|
158
|
-
visitedItemIdentifiers: cloneSessionSnapshot(sectionSlice?.visitedItemIdentifiers || []),
|
|
159
|
-
loadingComplete: sectionSlice?.loadingComplete === true,
|
|
160
|
-
totalRegistered: typeof sectionSlice?.totalRegistered === 'number' ? sectionSlice.totalRegistered : 0,
|
|
161
|
-
totalLoaded: typeof sectionSlice?.totalLoaded === 'number' ? sectionSlice.totalLoaded : 0,
|
|
162
|
-
itemsComplete: sectionSlice?.itemsComplete === true,
|
|
163
|
-
completedCount: typeof sectionSlice?.completedCount === 'number' ? sectionSlice.completedCount : 0,
|
|
164
|
-
totalItems: typeof sectionSlice?.totalItems === 'number' ? sectionSlice.totalItems : 0,
|
|
165
|
-
updatedAt: meta?.updatedAt || Date.now(),
|
|
166
|
-
lastChangedItemId: meta?.itemId || null,
|
|
167
|
-
itemSessions: cloneSessionSnapshot(
|
|
168
|
-
sectionSlice?.itemSessions || persistedSlice?.itemSessions || {}
|
|
169
|
-
)
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function detachControllerSubscription() {
|
|
174
|
-
unsubscribeController?.();
|
|
175
|
-
unsubscribeController = null;
|
|
176
|
-
subscriptionTarget.controller = null;
|
|
177
|
-
subscriptionTarget.sectionId = '';
|
|
178
|
-
subscriptionTarget.attemptId = undefined;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function detachLifecycleSubscription() {
|
|
182
|
-
unsubscribeLifecycle?.();
|
|
183
|
-
unsubscribeLifecycle = null;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function handleControllerEvent(detail: { itemId?: string; timestamp?: number }): void {
|
|
187
|
-
refreshFromController({
|
|
188
|
-
itemId: detail?.itemId,
|
|
189
|
-
updatedAt: detail?.timestamp || Date.now()
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function handleItemControllerEvent(detail: { itemId?: string; timestamp?: number }): void {
|
|
194
|
-
handleControllerEvent(detail);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function handleSectionControllerEvent(detail: { itemId?: string; timestamp?: number }): void {
|
|
198
|
-
handleControllerEvent(detail);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function ensureControllerSubscription() {
|
|
202
|
-
const controller = getController() || null;
|
|
203
|
-
if (!controller) {
|
|
204
|
-
detachControllerSubscription();
|
|
205
|
-
controllerAvailable = false;
|
|
206
|
-
sessionPanelSnapshot = {
|
|
207
|
-
currentItemIndex: null,
|
|
208
|
-
currentItemId: null,
|
|
209
|
-
visitedItemIdentifiers: [],
|
|
210
|
-
loadingComplete: false,
|
|
211
|
-
totalRegistered: 0,
|
|
212
|
-
totalLoaded: 0,
|
|
213
|
-
itemsComplete: false,
|
|
214
|
-
completedCount: 0,
|
|
215
|
-
totalItems: 0,
|
|
216
|
-
updatedAt: Date.now(),
|
|
217
|
-
lastChangedItemId: null,
|
|
218
|
-
itemSessions: {}
|
|
219
|
-
};
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
const nextAttemptId = attemptId || undefined;
|
|
223
|
-
const isSameTarget =
|
|
224
|
-
subscriptionTarget.controller === controller &&
|
|
225
|
-
subscriptionTarget.sectionId === sectionId &&
|
|
226
|
-
subscriptionTarget.attemptId === nextAttemptId;
|
|
227
|
-
if (isSameTarget && unsubscribeController) {
|
|
228
|
-
refreshFromController(undefined, controller);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
detachControllerSubscription();
|
|
232
|
-
const unsubscribeItem = toolkitCoordinator?.subscribeItemEvents?.({
|
|
233
|
-
listener: handleItemControllerEvent
|
|
234
|
-
}) || null;
|
|
235
|
-
const unsubscribeSection = toolkitCoordinator?.subscribeSectionLifecycleEvents?.({
|
|
236
|
-
listener: handleSectionControllerEvent
|
|
237
|
-
}) || null;
|
|
238
|
-
unsubscribeController = () => {
|
|
239
|
-
unsubscribeItem?.();
|
|
240
|
-
unsubscribeSection?.();
|
|
241
|
-
};
|
|
242
|
-
subscriptionTarget.controller = controller;
|
|
243
|
-
subscriptionTarget.sectionId = sectionId;
|
|
244
|
-
subscriptionTarget.attemptId = nextAttemptId;
|
|
245
|
-
refreshFromController(undefined, controller);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function queueEnsureControllerSubscription(): void {
|
|
249
|
-
if (resubscribeQueued) return;
|
|
250
|
-
resubscribeQueued = true;
|
|
251
|
-
queueMicrotask(() => {
|
|
252
|
-
resubscribeQueued = false;
|
|
253
|
-
ensureControllerSubscription();
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
$effect(() => {
|
|
258
|
-
if (!toolkitCoordinator || !sectionId) return;
|
|
259
|
-
ensureControllerSubscription();
|
|
260
|
-
detachLifecycleSubscription();
|
|
261
|
-
unsubscribeLifecycle = toolkitCoordinator.onSectionControllerLifecycle?.((event) => {
|
|
262
|
-
if (!isMatchingSectionControllerLifecycleEvent(event, sectionId, attemptId)) return;
|
|
263
|
-
queueEnsureControllerSubscription();
|
|
264
|
-
refreshFromController({
|
|
265
|
-
updatedAt: Date.now()
|
|
266
|
-
});
|
|
267
|
-
}) || null;
|
|
268
|
-
return () => {
|
|
269
|
-
detachControllerSubscription();
|
|
270
|
-
detachLifecycleSubscription();
|
|
271
|
-
};
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
</script>
|
|
275
|
-
|
|
276
|
-
<SharedFloatingPanel
|
|
277
|
-
title="Session Data"
|
|
278
|
-
ariaLabel="Drag session panel"
|
|
279
|
-
minWidth={340}
|
|
280
|
-
minHeight={260}
|
|
281
|
-
initialSizing={{
|
|
282
|
-
widthRatio: 0.29,
|
|
283
|
-
heightRatio: 0.72,
|
|
284
|
-
minWidth: 280,
|
|
285
|
-
maxWidth: 560,
|
|
286
|
-
minHeight: 360,
|
|
287
|
-
maxHeight: 860,
|
|
288
|
-
alignX: 'left',
|
|
289
|
-
alignY: 'center',
|
|
290
|
-
paddingX: 16,
|
|
291
|
-
paddingY: 16
|
|
292
|
-
}}
|
|
293
|
-
className="pie-section-player-tools-session-debugger"
|
|
294
|
-
bodyClass="pie-section-player-tools-session-debugger__content-shell"
|
|
295
|
-
onClose={() => dispatch('close')}
|
|
296
|
-
>
|
|
297
|
-
<svelte:fragment slot="icon">
|
|
298
|
-
<svg
|
|
299
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
300
|
-
class="pie-section-player-tools-session-debugger__icon-sm"
|
|
301
|
-
fill="none"
|
|
302
|
-
viewBox="0 0 24 24"
|
|
303
|
-
stroke="currentColor"
|
|
304
|
-
>
|
|
305
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
306
|
-
</svg>
|
|
307
|
-
</svelte:fragment>
|
|
308
|
-
|
|
309
|
-
<div class="pie-section-player-tools-session-debugger__content">
|
|
310
|
-
<div class="pie-section-player-tools-session-debugger__section-intro">
|
|
311
|
-
<div class="pie-section-player-tools-session-debugger__heading">PIE Session Data (Persistent)</div>
|
|
312
|
-
</div>
|
|
313
|
-
|
|
314
|
-
{#if !controllerAvailable}
|
|
315
|
-
<div class="pie-section-player-tools-session-debugger__alert pie-section-player-tools-session-debugger__alert--warning">
|
|
316
|
-
<svg
|
|
317
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
318
|
-
class="pie-section-player-tools-session-debugger__icon-md"
|
|
319
|
-
fill="none"
|
|
320
|
-
viewBox="0 0 24 24"
|
|
321
|
-
>
|
|
322
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M5.07 19h13.86c1.54 0 2.5-1.67 1.73-3L13.73 4c-.77-1.33-2.69-1.33-3.46 0L3.34 16c-.77 1.33.19 3 1.73 3z" />
|
|
323
|
-
</svg>
|
|
324
|
-
<span class="pie-section-player-tools-session-debugger__text-xs">Section controller not available for this section yet.</span>
|
|
325
|
-
</div>
|
|
326
|
-
{:else}
|
|
327
|
-
{#if Object.keys(sessionPanelSnapshot.itemSessions || {}).length === 0}
|
|
328
|
-
<div class="pie-section-player-tools-session-debugger__alert pie-section-player-tools-session-debugger__alert--info">
|
|
329
|
-
<svg
|
|
330
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
331
|
-
class="pie-section-player-tools-session-debugger__icon-md"
|
|
332
|
-
fill="none"
|
|
333
|
-
viewBox="0 0 24 24"
|
|
334
|
-
>
|
|
335
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
336
|
-
</svg>
|
|
337
|
-
<span class="pie-section-player-tools-session-debugger__text-xs">No section session data yet. Interact with the questions to see updates.</span>
|
|
338
|
-
</div>
|
|
339
|
-
{/if}
|
|
340
|
-
<div class="pie-section-player-tools-session-debugger__card">
|
|
341
|
-
<div class="pie-section-player-tools-session-debugger__card-title">
|
|
342
|
-
Item Sessions Snapshot
|
|
343
|
-
</div>
|
|
344
|
-
<div
|
|
345
|
-
class="pie-section-player-tools-session-debugger__card-region"
|
|
346
|
-
role="textbox"
|
|
347
|
-
aria-readonly="true"
|
|
348
|
-
tabindex="0"
|
|
349
|
-
aria-label="Section session snapshot JSON"
|
|
350
|
-
>
|
|
351
|
-
<pre class="pie-section-player-tools-session-debugger__card-pre">{JSON.stringify(sessionPanelSnapshot, null, 2)}</pre>
|
|
352
|
-
</div>
|
|
353
|
-
</div>
|
|
354
|
-
{/if}
|
|
355
|
-
</div>
|
|
356
|
-
</SharedFloatingPanel>
|
|
357
|
-
|
|
358
|
-
<style>
|
|
359
|
-
.pie-section-player-tools-session-debugger__icon-sm {
|
|
360
|
-
width: 1rem;
|
|
361
|
-
height: 1rem;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
.pie-section-player-tools-session-debugger__card-region:focus-visible {
|
|
365
|
-
outline: 2px solid var(--color-primary, #2563eb);
|
|
366
|
-
outline-offset: 2px;
|
|
367
|
-
border-radius: 0.5rem;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
</style>
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,8BAA8B,CAAC;AAEtC,YAAY,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../vite.config.ts"],"names":[],"mappings":";AAKA,wBAkCG"}
|