@pie-players/pie-section-player-tools-session-debugger 0.3.4 → 0.3.7
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/SectionSessionPanel.svelte +117 -67
- package/dist/section-player-tools-session-debugger.js +1217 -1179
- package/package.json +3 -3
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
currentItemIndex: number | null;
|
|
30
30
|
currentItemId: string | null;
|
|
31
31
|
visitedItemIdentifiers: string[];
|
|
32
|
+
loadingComplete: boolean;
|
|
33
|
+
totalRegistered: number;
|
|
34
|
+
totalLoaded: number;
|
|
35
|
+
itemsComplete: boolean;
|
|
36
|
+
completedCount: number;
|
|
37
|
+
totalItems: number;
|
|
32
38
|
updatedAt: number | null;
|
|
33
39
|
lastChangedItemId: string | null;
|
|
34
40
|
itemSessions: Record<string, unknown>;
|
|
@@ -39,15 +45,36 @@
|
|
|
39
45
|
currentItemId?: string;
|
|
40
46
|
visitedItemIdentifiers?: string[];
|
|
41
47
|
itemSessions?: Record<string, unknown>;
|
|
48
|
+
loadingComplete?: boolean;
|
|
49
|
+
totalRegistered?: number;
|
|
50
|
+
totalLoaded?: number;
|
|
51
|
+
itemsComplete?: boolean;
|
|
52
|
+
completedCount?: number;
|
|
53
|
+
totalItems?: number;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
type SectionSessionStateLike = {
|
|
57
|
+
itemSessions?: Record<string, unknown>;
|
|
42
58
|
};
|
|
43
59
|
|
|
44
60
|
type SectionControllerLike = {
|
|
45
|
-
|
|
61
|
+
getRuntimeState?: () => SectionAttemptSliceLike | null;
|
|
62
|
+
getSession?: () => SectionSessionStateLike | null;
|
|
46
63
|
subscribe?: (listener: (event: { itemId?: string; timestamp?: number }) => void) => () => void;
|
|
47
64
|
};
|
|
48
65
|
|
|
49
66
|
type ToolkitCoordinatorLike = {
|
|
50
67
|
getSectionController?: (args: { sectionId: string; attemptId?: string }) => SectionControllerLike | undefined;
|
|
68
|
+
subscribeItemEvents?: (args: {
|
|
69
|
+
sectionId: string;
|
|
70
|
+
attemptId?: string;
|
|
71
|
+
listener: (event: { itemId?: string; timestamp?: number }) => void;
|
|
72
|
+
}) => () => void;
|
|
73
|
+
subscribeSectionLifecycleEvents?: (args: {
|
|
74
|
+
sectionId: string;
|
|
75
|
+
attemptId?: string;
|
|
76
|
+
listener: (event: { itemId?: string; timestamp?: number }) => void;
|
|
77
|
+
}) => () => void;
|
|
51
78
|
onSectionControllerLifecycle?: (
|
|
52
79
|
listener: (event: { type: 'ready' | 'disposed'; key?: { sectionId?: string; attemptId?: string } }) => void
|
|
53
80
|
) => () => void;
|
|
@@ -73,15 +100,29 @@
|
|
|
73
100
|
currentItemIndex: null,
|
|
74
101
|
currentItemId: null,
|
|
75
102
|
visitedItemIdentifiers: [],
|
|
103
|
+
loadingComplete: false,
|
|
104
|
+
totalRegistered: 0,
|
|
105
|
+
totalLoaded: 0,
|
|
106
|
+
itemsComplete: false,
|
|
107
|
+
completedCount: 0,
|
|
108
|
+
totalItems: 0,
|
|
76
109
|
updatedAt: null,
|
|
77
110
|
lastChangedItemId: null,
|
|
78
111
|
itemSessions: {}
|
|
79
112
|
});
|
|
80
|
-
let activeController: SectionControllerLike | null = null;
|
|
81
113
|
let unsubscribeController: (() => void) | null = null;
|
|
82
114
|
let unsubscribeLifecycle: (() => void) | null = null;
|
|
83
115
|
let controllerAvailable = $state(false);
|
|
84
|
-
let
|
|
116
|
+
let resubscribeQueued = false;
|
|
117
|
+
const subscriptionTarget: {
|
|
118
|
+
controller: SectionControllerLike | null;
|
|
119
|
+
sectionId: string;
|
|
120
|
+
attemptId?: string;
|
|
121
|
+
} = {
|
|
122
|
+
controller: null,
|
|
123
|
+
sectionId: '',
|
|
124
|
+
attemptId: undefined
|
|
125
|
+
};
|
|
85
126
|
|
|
86
127
|
function cloneSessionSnapshot<T>(value: T): T {
|
|
87
128
|
try {
|
|
@@ -111,7 +152,8 @@
|
|
|
111
152
|
controllerOverride?: SectionControllerLike | null
|
|
112
153
|
) {
|
|
113
154
|
const controller = controllerOverride || getController();
|
|
114
|
-
const sectionSlice = controller?.
|
|
155
|
+
const sectionSlice = controller?.getRuntimeState?.() || null;
|
|
156
|
+
const persistedSlice = controller?.getSession?.() || null;
|
|
115
157
|
controllerAvailable = Boolean(controller);
|
|
116
158
|
sessionPanelSnapshot = {
|
|
117
159
|
currentItemIndex:
|
|
@@ -123,30 +165,26 @@
|
|
|
123
165
|
? sectionSlice.currentItemId
|
|
124
166
|
: null,
|
|
125
167
|
visitedItemIdentifiers: cloneSessionSnapshot(sectionSlice?.visitedItemIdentifiers || []),
|
|
168
|
+
loadingComplete: sectionSlice?.loadingComplete === true,
|
|
169
|
+
totalRegistered: typeof sectionSlice?.totalRegistered === 'number' ? sectionSlice.totalRegistered : 0,
|
|
170
|
+
totalLoaded: typeof sectionSlice?.totalLoaded === 'number' ? sectionSlice.totalLoaded : 0,
|
|
171
|
+
itemsComplete: sectionSlice?.itemsComplete === true,
|
|
172
|
+
completedCount: typeof sectionSlice?.completedCount === 'number' ? sectionSlice.completedCount : 0,
|
|
173
|
+
totalItems: typeof sectionSlice?.totalItems === 'number' ? sectionSlice.totalItems : 0,
|
|
126
174
|
updatedAt: meta?.updatedAt || Date.now(),
|
|
127
175
|
lastChangedItemId: meta?.itemId || null,
|
|
128
|
-
itemSessions: cloneSessionSnapshot(
|
|
176
|
+
itemSessions: cloneSessionSnapshot(
|
|
177
|
+
sectionSlice?.itemSessions || persistedSlice?.itemSessions || {}
|
|
178
|
+
)
|
|
129
179
|
};
|
|
130
180
|
}
|
|
131
181
|
|
|
132
|
-
function queueRefresh(meta?: { itemId?: string; updatedAt?: number }) {
|
|
133
|
-
if (refreshQueued) return;
|
|
134
|
-
refreshQueued = true;
|
|
135
|
-
queueMicrotask(() => {
|
|
136
|
-
refreshQueued = false;
|
|
137
|
-
ensureControllerSubscription();
|
|
138
|
-
refreshFromController(
|
|
139
|
-
meta || {
|
|
140
|
-
updatedAt: Date.now()
|
|
141
|
-
}
|
|
142
|
-
);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
182
|
function detachControllerSubscription() {
|
|
147
183
|
unsubscribeController?.();
|
|
148
184
|
unsubscribeController = null;
|
|
149
|
-
|
|
185
|
+
subscriptionTarget.controller = null;
|
|
186
|
+
subscriptionTarget.sectionId = '';
|
|
187
|
+
subscriptionTarget.attemptId = undefined;
|
|
150
188
|
}
|
|
151
189
|
|
|
152
190
|
function detachLifecycleSubscription() {
|
|
@@ -154,6 +192,13 @@
|
|
|
154
192
|
unsubscribeLifecycle = null;
|
|
155
193
|
}
|
|
156
194
|
|
|
195
|
+
function handleControllerEvent(detail: { itemId?: string; timestamp?: number }): void {
|
|
196
|
+
refreshFromController({
|
|
197
|
+
itemId: detail?.itemId,
|
|
198
|
+
updatedAt: detail?.timestamp || Date.now()
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
157
202
|
function ensureControllerSubscription() {
|
|
158
203
|
const controller = getController() || null;
|
|
159
204
|
if (!controller) {
|
|
@@ -163,32 +208,54 @@
|
|
|
163
208
|
currentItemIndex: null,
|
|
164
209
|
currentItemId: null,
|
|
165
210
|
visitedItemIdentifiers: [],
|
|
211
|
+
loadingComplete: false,
|
|
212
|
+
totalRegistered: 0,
|
|
213
|
+
totalLoaded: 0,
|
|
214
|
+
itemsComplete: false,
|
|
215
|
+
completedCount: 0,
|
|
216
|
+
totalItems: 0,
|
|
166
217
|
updatedAt: Date.now(),
|
|
167
218
|
lastChangedItemId: null,
|
|
168
219
|
itemSessions: {}
|
|
169
220
|
};
|
|
170
221
|
return;
|
|
171
222
|
}
|
|
172
|
-
|
|
223
|
+
const nextAttemptId = attemptId || undefined;
|
|
224
|
+
const isSameTarget =
|
|
225
|
+
subscriptionTarget.controller === controller &&
|
|
226
|
+
subscriptionTarget.sectionId === sectionId &&
|
|
227
|
+
subscriptionTarget.attemptId === nextAttemptId;
|
|
228
|
+
if (isSameTarget && unsubscribeController) {
|
|
229
|
+
refreshFromController(undefined, controller);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
173
232
|
detachControllerSubscription();
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
233
|
+
const unsubscribeItem = toolkitCoordinator?.subscribeItemEvents?.({
|
|
234
|
+
sectionId,
|
|
235
|
+
attemptId,
|
|
236
|
+
listener: handleControllerEvent
|
|
237
|
+
}) || null;
|
|
238
|
+
const unsubscribeSection = toolkitCoordinator?.subscribeSectionLifecycleEvents?.({
|
|
239
|
+
sectionId,
|
|
240
|
+
attemptId,
|
|
241
|
+
listener: handleControllerEvent
|
|
242
|
+
}) || null;
|
|
243
|
+
unsubscribeController = () => {
|
|
244
|
+
unsubscribeItem?.();
|
|
245
|
+
unsubscribeSection?.();
|
|
246
|
+
};
|
|
247
|
+
subscriptionTarget.controller = controller;
|
|
248
|
+
subscriptionTarget.sectionId = sectionId;
|
|
249
|
+
subscriptionTarget.attemptId = nextAttemptId;
|
|
186
250
|
refreshFromController(undefined, controller);
|
|
187
251
|
}
|
|
188
252
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
253
|
+
function queueEnsureControllerSubscription(): void {
|
|
254
|
+
if (resubscribeQueued) return;
|
|
255
|
+
resubscribeQueued = true;
|
|
256
|
+
queueMicrotask(() => {
|
|
257
|
+
resubscribeQueued = false;
|
|
258
|
+
ensureControllerSubscription();
|
|
192
259
|
});
|
|
193
260
|
}
|
|
194
261
|
|
|
@@ -198,7 +265,7 @@
|
|
|
198
265
|
detachLifecycleSubscription();
|
|
199
266
|
unsubscribeLifecycle = toolkitCoordinator.onSectionControllerLifecycle?.((event) => {
|
|
200
267
|
if (!isMatchingSectionControllerLifecycleEvent(event, sectionId, attemptId)) return;
|
|
201
|
-
|
|
268
|
+
queueEnsureControllerSubscription();
|
|
202
269
|
refreshFromController({
|
|
203
270
|
updatedAt: Date.now()
|
|
204
271
|
});
|
|
@@ -229,20 +296,6 @@
|
|
|
229
296
|
sessionWindowY = initial.y;
|
|
230
297
|
sessionWindowWidth = initial.width;
|
|
231
298
|
sessionWindowHeight = initial.height;
|
|
232
|
-
|
|
233
|
-
const handleRuntimeSessionEvent = () => {
|
|
234
|
-
queueRefresh({
|
|
235
|
-
updatedAt: Date.now()
|
|
236
|
-
});
|
|
237
|
-
};
|
|
238
|
-
document.addEventListener('session-changed', handleRuntimeSessionEvent as EventListener, true);
|
|
239
|
-
document.addEventListener('item-session-changed', handleRuntimeSessionEvent as EventListener, true);
|
|
240
|
-
document.addEventListener('composition-changed', handleRuntimeSessionEvent as EventListener, true);
|
|
241
|
-
return () => {
|
|
242
|
-
document.removeEventListener('session-changed', handleRuntimeSessionEvent as EventListener, true);
|
|
243
|
-
document.removeEventListener('item-session-changed', handleRuntimeSessionEvent as EventListener, true);
|
|
244
|
-
document.removeEventListener('composition-changed', handleRuntimeSessionEvent as EventListener, true);
|
|
245
|
-
};
|
|
246
299
|
});
|
|
247
300
|
|
|
248
301
|
const pointerController = createFloatingPanelPointerController({
|
|
@@ -320,19 +373,20 @@
|
|
|
320
373
|
</svg>
|
|
321
374
|
<span class="pie-section-player-tools-session-debugger__text-xs">Section controller not available for this section yet.</span>
|
|
322
375
|
</div>
|
|
323
|
-
{:else if Object.keys(sessionPanelSnapshot.itemSessions || {}).length === 0}
|
|
324
|
-
<div class="pie-section-player-tools-session-debugger__alert pie-section-player-tools-session-debugger__alert--info">
|
|
325
|
-
<svg
|
|
326
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
327
|
-
class="pie-section-player-tools-session-debugger__icon-md"
|
|
328
|
-
fill="none"
|
|
329
|
-
viewBox="0 0 24 24"
|
|
330
|
-
>
|
|
331
|
-
<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" />
|
|
332
|
-
</svg>
|
|
333
|
-
<span class="pie-section-player-tools-session-debugger__text-xs">No section session data yet. Interact with the questions to see updates.</span>
|
|
334
|
-
</div>
|
|
335
376
|
{:else}
|
|
377
|
+
{#if Object.keys(sessionPanelSnapshot.itemSessions || {}).length === 0}
|
|
378
|
+
<div class="pie-section-player-tools-session-debugger__alert pie-section-player-tools-session-debugger__alert--info">
|
|
379
|
+
<svg
|
|
380
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
381
|
+
class="pie-section-player-tools-session-debugger__icon-md"
|
|
382
|
+
fill="none"
|
|
383
|
+
viewBox="0 0 24 24"
|
|
384
|
+
>
|
|
385
|
+
<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" />
|
|
386
|
+
</svg>
|
|
387
|
+
<span class="pie-section-player-tools-session-debugger__text-xs">No section session data yet. Interact with the questions to see updates.</span>
|
|
388
|
+
</div>
|
|
389
|
+
{/if}
|
|
336
390
|
<div class="pie-section-player-tools-session-debugger__card">
|
|
337
391
|
<div class="pie-section-player-tools-session-debugger__card-title">
|
|
338
392
|
Item Sessions Snapshot
|
|
@@ -401,8 +455,4 @@
|
|
|
401
455
|
min-height: 0;
|
|
402
456
|
}
|
|
403
457
|
|
|
404
|
-
.pie-section-player-tools-session-debugger__resize-handle {
|
|
405
|
-
user-select: none;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
458
|
</style>
|