@pie-players/pie-assessment-toolkit 0.3.68 → 0.3.69
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 +80 -8
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-pe5szfyx.js +46 -0
- package/dist/components/chunks/ItemToolBar-rd7te9r0.js +51 -0
- package/dist/policy/core/compose-decision.js +14 -0
- package/dist/policy/core/decision-types.d.ts +1 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +8 -0
- package/dist/policy/sources/PnpPolicySource.js +19 -10
- package/dist/services/ToolRegistry.d.ts +34 -0
- package/dist/services/ToolRegistry.js +34 -0
- package/dist/services/tool-context.js +8 -3
- package/dist/services/tool-providers/CortexToolProvider.d.ts +18 -0
- package/dist/services/tool-providers/CortexToolProvider.js +32 -0
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +13 -102
- package/dist/services/tool-providers/DesmosToolProvider.js +14 -145
- package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +21 -0
- package/dist/services/tool-providers/GeoGebraToolProvider.js +32 -0
- package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +35 -0
- package/dist/services/tool-providers/LazyCalculatorToolProvider.js +95 -0
- package/dist/services/tool-providers/index.d.ts +4 -0
- package/dist/services/tool-providers/index.js +2 -0
- package/dist/tools/client.d.ts +0 -1
- package/dist/tools/client.js +0 -2
- package/dist/tools/internal.d.ts +1 -1
- package/dist/tools/internal.js +1 -1
- package/dist/tools/types.d.ts +1 -66
- package/package.json +22 -12
- package/dist/components/chunks/ItemToolBar-38mhtjsq.js +0 -51
- package/dist/components/chunks/ItemToolBar-9ymm7pd1.js +0 -46
- package/dist/tools/library-loader.d.ts +0 -62
- package/dist/tools/library-loader.js +0 -261
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Library Loader Service
|
|
3
|
-
* Dynamically loads external JavaScript libraries with retry logic and fallback URLs
|
|
4
|
-
*
|
|
5
|
-
* Based on architectural enhancements from renaissance-tool-analyses.md
|
|
6
|
-
* Supports both static and dynamic library loading
|
|
7
|
-
*/
|
|
8
|
-
import type { LibraryConfig, LibraryLoader, LoaderStats } from "./types.js";
|
|
9
|
-
/**
|
|
10
|
-
* Implementation of LibraryLoader service
|
|
11
|
-
*/
|
|
12
|
-
export declare class LibraryLoaderImpl implements LibraryLoader {
|
|
13
|
-
private loadedLibraries;
|
|
14
|
-
private pendingLoads;
|
|
15
|
-
private failedLibraries;
|
|
16
|
-
private stats;
|
|
17
|
-
/**
|
|
18
|
-
* Load a JavaScript library
|
|
19
|
-
*/
|
|
20
|
-
loadScript(library: LibraryConfig): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Load a stylesheet
|
|
23
|
-
*/
|
|
24
|
-
loadStylesheet(url: string, targetRoot?: Document | ShadowRoot): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Check if a library is already loaded
|
|
27
|
-
*/
|
|
28
|
-
isLoaded(libraryId: string): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Preload multiple libraries in parallel
|
|
31
|
-
*/
|
|
32
|
-
preload(libraries: LibraryConfig[]): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Unload a library (remove script tag)
|
|
35
|
-
*/
|
|
36
|
-
unload(libraryId: string): void;
|
|
37
|
-
/**
|
|
38
|
-
* Get loader statistics
|
|
39
|
-
*/
|
|
40
|
-
getStats(): LoaderStats;
|
|
41
|
-
/**
|
|
42
|
-
* Load script with retry logic
|
|
43
|
-
*/
|
|
44
|
-
private _loadScriptWithRetry;
|
|
45
|
-
/**
|
|
46
|
-
* Load script from a specific URL
|
|
47
|
-
*/
|
|
48
|
-
private _loadScriptFromUrl;
|
|
49
|
-
/**
|
|
50
|
-
* Sleep utility for retry delays
|
|
51
|
-
*/
|
|
52
|
-
private _sleep;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Singleton instance
|
|
56
|
-
*/
|
|
57
|
-
export declare const libraryLoader: LibraryLoaderImpl;
|
|
58
|
-
/**
|
|
59
|
-
* Common library configurations
|
|
60
|
-
* Based on industry best practices and platform analyses
|
|
61
|
-
*/
|
|
62
|
-
export declare const COMMON_LIBRARIES: Record<string, LibraryConfig>;
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Library Loader Service
|
|
3
|
-
* Dynamically loads external JavaScript libraries with retry logic and fallback URLs
|
|
4
|
-
*
|
|
5
|
-
* Based on architectural enhancements from renaissance-tool-analyses.md
|
|
6
|
-
* Supports both static and dynamic library loading
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Implementation of LibraryLoader service
|
|
10
|
-
*/
|
|
11
|
-
export class LibraryLoaderImpl {
|
|
12
|
-
loadedLibraries = new Set();
|
|
13
|
-
pendingLoads = new Map();
|
|
14
|
-
failedLibraries = new Map();
|
|
15
|
-
stats = {
|
|
16
|
-
loaded: [],
|
|
17
|
-
failed: [],
|
|
18
|
-
pending: [],
|
|
19
|
-
cacheHits: 0,
|
|
20
|
-
cacheMisses: 0,
|
|
21
|
-
totalLoadTime: 0,
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Load a JavaScript library
|
|
25
|
-
*/
|
|
26
|
-
async loadScript(library) {
|
|
27
|
-
// SSR guard: Library loading should NEVER run on the server
|
|
28
|
-
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
29
|
-
throw new Error("Library loader can only be used in the browser");
|
|
30
|
-
}
|
|
31
|
-
const startTime = performance.now();
|
|
32
|
-
// Check if already loaded
|
|
33
|
-
if (this.isLoaded(library.id)) {
|
|
34
|
-
this.stats.cacheHits++;
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Check if already pending
|
|
38
|
-
const pending = this.pendingLoads.get(library.id);
|
|
39
|
-
if (pending) {
|
|
40
|
-
return pending;
|
|
41
|
-
}
|
|
42
|
-
this.stats.cacheMisses++;
|
|
43
|
-
// Start loading
|
|
44
|
-
const loadPromise = this._loadScriptWithRetry(library);
|
|
45
|
-
this.pendingLoads.set(library.id, loadPromise);
|
|
46
|
-
this.stats.pending.push(library.id);
|
|
47
|
-
try {
|
|
48
|
-
await loadPromise;
|
|
49
|
-
this.loadedLibraries.add(library.id);
|
|
50
|
-
this.stats.loaded.push(library.id);
|
|
51
|
-
const loadTime = performance.now() - startTime;
|
|
52
|
-
this.stats.totalLoadTime += loadTime;
|
|
53
|
-
console.log(`[LibraryLoader] Successfully loaded ${library.id} in ${loadTime.toFixed(2)}ms`);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
this.failedLibraries.set(library.id, error);
|
|
57
|
-
this.stats.failed.push(library.id);
|
|
58
|
-
console.error(`[LibraryLoader] Failed to load ${library.id}:`, error);
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
finally {
|
|
62
|
-
this.pendingLoads.delete(library.id);
|
|
63
|
-
const pendingIndex = this.stats.pending.indexOf(library.id);
|
|
64
|
-
if (pendingIndex !== -1) {
|
|
65
|
-
this.stats.pending.splice(pendingIndex, 1);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Load a stylesheet
|
|
71
|
-
*/
|
|
72
|
-
async loadStylesheet(url, targetRoot) {
|
|
73
|
-
// SSR guard: Stylesheet loading should NEVER run on the server
|
|
74
|
-
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
75
|
-
throw new Error("Stylesheet loader can only be used in the browser");
|
|
76
|
-
}
|
|
77
|
-
return new Promise((resolve, reject) => {
|
|
78
|
-
const root = targetRoot ?? document;
|
|
79
|
-
// Check if already loaded
|
|
80
|
-
const existing = root.querySelector(`link[href="${url}"]`);
|
|
81
|
-
if (existing) {
|
|
82
|
-
resolve();
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const link = document.createElement("link");
|
|
86
|
-
link.rel = "stylesheet";
|
|
87
|
-
link.href = url;
|
|
88
|
-
link.onload = () => resolve();
|
|
89
|
-
link.onerror = () => reject(new Error(`Failed to load stylesheet: ${url}`));
|
|
90
|
-
if (root instanceof ShadowRoot) {
|
|
91
|
-
root.appendChild(link);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
document.head.appendChild(link);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Check if a library is already loaded
|
|
99
|
-
*/
|
|
100
|
-
isLoaded(libraryId) {
|
|
101
|
-
return this.loadedLibraries.has(libraryId);
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Preload multiple libraries in parallel
|
|
105
|
-
*/
|
|
106
|
-
async preload(libraries) {
|
|
107
|
-
const promises = libraries.map((lib) => this.loadScript(lib));
|
|
108
|
-
await Promise.all(promises);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Unload a library (remove script tag)
|
|
112
|
-
*/
|
|
113
|
-
unload(libraryId) {
|
|
114
|
-
const script = document.querySelector(`script[data-library-id="${libraryId}"]`);
|
|
115
|
-
if (script) {
|
|
116
|
-
script.remove();
|
|
117
|
-
this.loadedLibraries.delete(libraryId);
|
|
118
|
-
// Remove from stats
|
|
119
|
-
const loadedIndex = this.stats.loaded.indexOf(libraryId);
|
|
120
|
-
if (loadedIndex !== -1) {
|
|
121
|
-
this.stats.loaded.splice(loadedIndex, 1);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Get loader statistics
|
|
127
|
-
*/
|
|
128
|
-
getStats() {
|
|
129
|
-
return { ...this.stats };
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Load script with retry logic
|
|
133
|
-
*/
|
|
134
|
-
async _loadScriptWithRetry(library) {
|
|
135
|
-
const urls = [library.url, ...(library.fallbackUrls || [])];
|
|
136
|
-
const maxAttempts = library.retry?.maxAttempts || 3;
|
|
137
|
-
const delay = library.retry?.delay || 1000;
|
|
138
|
-
const backoffMultiplier = library.retry?.backoffMultiplier || 2;
|
|
139
|
-
let lastError = null;
|
|
140
|
-
for (const url of urls) {
|
|
141
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
142
|
-
try {
|
|
143
|
-
await this._loadScriptFromUrl(url, library);
|
|
144
|
-
// Verify library loaded if globalVar specified
|
|
145
|
-
if (library.globalVar) {
|
|
146
|
-
if (!(library.globalVar in window)) {
|
|
147
|
-
throw new Error(`Library ${library.id} loaded but global ${library.globalVar} not found`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return; // Success
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
lastError = error;
|
|
154
|
-
console.warn(`[LibraryLoader] Attempt ${attempt}/${maxAttempts} failed for ${url}:`, error);
|
|
155
|
-
// Wait before retry (exponential backoff)
|
|
156
|
-
if (attempt < maxAttempts) {
|
|
157
|
-
const waitTime = delay * Math.pow(backoffMultiplier, attempt - 1);
|
|
158
|
-
await this._sleep(waitTime);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
throw new Error(`Failed to load library ${library.id} after trying all URLs: ${lastError?.message}`);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Load script from a specific URL
|
|
167
|
-
*/
|
|
168
|
-
_loadScriptFromUrl(url, library) {
|
|
169
|
-
return new Promise((resolve, reject) => {
|
|
170
|
-
const script = document.createElement("script");
|
|
171
|
-
script.src = url;
|
|
172
|
-
script.dataset.libraryId = library.id;
|
|
173
|
-
if (library.async)
|
|
174
|
-
script.async = true;
|
|
175
|
-
if (library.defer)
|
|
176
|
-
script.defer = true;
|
|
177
|
-
if (library.integrity)
|
|
178
|
-
script.integrity = library.integrity;
|
|
179
|
-
if (library.crossorigin)
|
|
180
|
-
script.crossOrigin = library.crossorigin;
|
|
181
|
-
let timeoutId;
|
|
182
|
-
const cleanup = () => {
|
|
183
|
-
if (timeoutId)
|
|
184
|
-
clearTimeout(timeoutId);
|
|
185
|
-
script.onload = null;
|
|
186
|
-
script.onerror = null;
|
|
187
|
-
};
|
|
188
|
-
script.onload = () => {
|
|
189
|
-
cleanup();
|
|
190
|
-
resolve();
|
|
191
|
-
};
|
|
192
|
-
script.onerror = (error) => {
|
|
193
|
-
cleanup();
|
|
194
|
-
script.remove();
|
|
195
|
-
reject(new Error(`Script load error for ${url}: ${error}`));
|
|
196
|
-
};
|
|
197
|
-
// Timeout handling
|
|
198
|
-
if (library.timeout) {
|
|
199
|
-
timeoutId = window.setTimeout(() => {
|
|
200
|
-
cleanup();
|
|
201
|
-
script.remove();
|
|
202
|
-
reject(new Error(`Script load timeout for ${url} after ${library.timeout}ms`));
|
|
203
|
-
}, library.timeout);
|
|
204
|
-
}
|
|
205
|
-
document.head.appendChild(script);
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Sleep utility for retry delays
|
|
210
|
-
*/
|
|
211
|
-
_sleep(ms) {
|
|
212
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Singleton instance
|
|
217
|
-
*/
|
|
218
|
-
export const libraryLoader = new LibraryLoaderImpl();
|
|
219
|
-
/**
|
|
220
|
-
* Desmos library version (matches the version in calculator.js)
|
|
221
|
-
* Update this when upgrading to a new version
|
|
222
|
-
*/
|
|
223
|
-
const DESMOS_VERSION = "v1.12";
|
|
224
|
-
/**
|
|
225
|
-
* Common library configurations
|
|
226
|
-
* Based on industry best practices and platform analyses
|
|
227
|
-
*/
|
|
228
|
-
export const COMMON_LIBRARIES = {
|
|
229
|
-
desmos: {
|
|
230
|
-
id: "desmos",
|
|
231
|
-
url: `/lib/desmos/${DESMOS_VERSION}/calculator.js`, // Self-hosted (prioritized) - versioned for better cache control
|
|
232
|
-
fallbackUrls: [
|
|
233
|
-
"https://www.desmos.com/api/v1.12/calculator.js",
|
|
234
|
-
"https://cdn.jsdelivr.net/npm/desmos@1.12/dist/calculator.js",
|
|
235
|
-
],
|
|
236
|
-
globalVar: "Desmos",
|
|
237
|
-
timeout: 10000,
|
|
238
|
-
retry: { maxAttempts: 3, delay: 1000, backoffMultiplier: 2 },
|
|
239
|
-
},
|
|
240
|
-
mathjax: {
|
|
241
|
-
id: "mathjax",
|
|
242
|
-
url: "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js",
|
|
243
|
-
fallbackUrls: [
|
|
244
|
-
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js",
|
|
245
|
-
"/static/lib/mathjax/tex-mml-chtml.js",
|
|
246
|
-
],
|
|
247
|
-
globalVar: "MathJax",
|
|
248
|
-
async: true,
|
|
249
|
-
retry: { maxAttempts: 2, delay: 1500 },
|
|
250
|
-
},
|
|
251
|
-
katex: {
|
|
252
|
-
id: "katex",
|
|
253
|
-
url: "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js",
|
|
254
|
-
fallbackUrls: [
|
|
255
|
-
"https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.js",
|
|
256
|
-
"/static/lib/katex/katex.min.js",
|
|
257
|
-
],
|
|
258
|
-
globalVar: "katex",
|
|
259
|
-
timeout: 5000,
|
|
260
|
-
},
|
|
261
|
-
};
|