lido-standalone 0.0.0-beta-19-dev → 0.0.0-beta-20-dev

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.
Files changed (37) hide show
  1. package/dist/cjs/{index-52f24ddb.js → index-9a2514de.js} +3 -1
  2. package/dist/cjs/index-9a2514de.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +1 -1
  4. package/dist/cjs/lido-standalone.cjs.entry.js +114 -65
  5. package/dist/cjs/lido-standalone.cjs.entry.js.map +1 -1
  6. package/dist/cjs/lido-standalone.cjs.js +2 -2
  7. package/dist/cjs/loader.cjs.js +2 -2
  8. package/dist/collection/components/lido-standalone/lido-standalone.js +148 -63
  9. package/dist/collection/components/lido-standalone/lido-standalone.js.map +1 -1
  10. package/dist/components/lido-standalone.js +117 -65
  11. package/dist/components/lido-standalone.js.map +1 -1
  12. package/dist/esm/{index-5da3b4be.js → index-32cd7d72.js} +3 -2
  13. package/dist/esm/index-32cd7d72.js.map +1 -0
  14. package/dist/esm/index.js +1 -1
  15. package/dist/esm/lido-standalone.entry.js +114 -65
  16. package/dist/esm/lido-standalone.entry.js.map +1 -1
  17. package/dist/esm/lido-standalone.js +3 -3
  18. package/dist/esm/loader.js +3 -3
  19. package/dist/lido-standalone/index.esm.js +1 -1
  20. package/dist/lido-standalone/lido-standalone.esm.js +1 -1
  21. package/dist/lido-standalone/lido-standalone.esm.js.map +1 -1
  22. package/dist/lido-standalone/p-1469ddb8.js +3 -0
  23. package/dist/lido-standalone/p-1469ddb8.js.map +1 -0
  24. package/dist/lido-standalone/p-862a6695.entry.js +2 -0
  25. package/dist/lido-standalone/p-862a6695.entry.js.map +1 -0
  26. package/dist/types/components/lido-standalone/lido-standalone.d.ts +13 -3
  27. package/dist/types/components.d.ts +16 -0
  28. package/package.json +1 -1
  29. package/src/components/lido-standalone/lido-standalone.tsx +142 -77
  30. package/src/components/lido-standalone/readme.md +2 -0
  31. package/src/components.d.ts +16 -0
  32. package/dist/cjs/index-52f24ddb.js.map +0 -1
  33. package/dist/esm/index-5da3b4be.js.map +0 -1
  34. package/dist/lido-standalone/p-1bb50e6d.entry.js +0 -2
  35. package/dist/lido-standalone/p-1bb50e6d.entry.js.map +0 -1
  36. package/dist/lido-standalone/p-3a3323c8.js +0 -3
  37. package/dist/lido-standalone/p-3a3323c8.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Component, Prop, State, Watch, h } from '@stencil/core';
1
+ import { Component, Element, Prop, State, Watch, h } from '@stencil/core';
2
2
 
3
3
  /**
4
4
  * <lido-standalone> usage example:
@@ -21,6 +21,8 @@ import { Component, Prop, State, Watch, h } from '@stencil/core';
21
21
  shadow: false,
22
22
  })
23
23
  export class LidoStandalone {
24
+ @Element() hostElement!: HTMLElement;
25
+
24
26
  /**
25
27
  * The public URL where the unzipped Lido code is hosted, e.g.
26
28
  * "https://example.com/path/to/lido-game".
@@ -47,11 +49,19 @@ export class LidoStandalone {
47
49
  /** The height prop to pass to <lido-home>. Defaults to "75vh". */
48
50
  @Prop() height: string = '75vh';
49
51
 
52
+ /** The language prop to pass to <lido-home>. */
53
+ @Prop() language?: string;
54
+
50
55
  /**
51
56
  * Optional prop for directly providing XML data instead of fetching.
52
57
  */
53
58
  @Prop() xmlData?: string;
54
59
 
60
+ /**
61
+ * To pass zip file directly to <lido-home> as its attribute.
62
+ */
63
+ @Prop() zipUrl?: string;
64
+
55
65
  /**
56
66
  * If provided(in index.html) → tries versioned script loading from config.json.
57
67
  * If no version is found → automatically falls back to default player loading.
@@ -82,6 +92,12 @@ export class LidoStandalone {
82
92
  this.fetchXmlData();
83
93
  }
84
94
 
95
+ // Re-apply inline XML whenever the host prop changes.
96
+ @Watch('xmlData')
97
+ onXmlDataChange() {
98
+ this.fetchXmlData();
99
+ }
100
+
85
101
  componentWillLoad() {
86
102
  // 1) Attempt to inject the Lido scripts from baseUrl
87
103
  this.injectLidoScripts();
@@ -107,102 +123,152 @@ export class LidoStandalone {
107
123
  const scriptCheckUrl = `${cleanBase}/code/lido-player.esm.js`;
108
124
  const fileExists = this.doesFileExistSync(scriptCheckUrl);
109
125
 
126
+ // --------------- CASE: NO codeFolderPath PROVIDED ---------------
127
+ // Try loading version from default /code_versions folder
128
+ // --------------- SINGLE CASE: codeFolderPath PROVIDED ---------------
129
+
110
130
  if (fileExists) {
131
+ console.log("Using code from zip....")
111
132
  // If it exists, inject them
112
133
  const scriptEsm = document.createElement('script');
113
134
  scriptEsm.type = 'module';
114
135
  scriptEsm.src = scriptCheckUrl;
115
136
  document.head.appendChild(scriptEsm);
116
-
117
137
  // (Optional) NoModule script for older browsers
118
138
  const scriptNoModule = document.createElement('script');
119
139
  scriptNoModule.setAttribute('nomodule', '');
120
140
  scriptNoModule.src = `${cleanBase}/code/lido-player.js`;
121
141
  document.head.appendChild(scriptNoModule);
122
-
123
142
  this.scriptsInjected = true;
124
143
  console.debug('Lido scripts injected from:', this.baseUrl);
144
+ return;
125
145
  }
146
+
147
+ if (this.codeFolderPath) {
148
+ const cleanBase = this.baseUrl.replace(/\/+$/, "");
149
+ try {
150
+ const lessonCfgUrl = `${cleanBase}/config.json`;
151
+ try {
152
+ // 1️⃣ Load lesson config.json safely
153
+ let lessonCfg: any = {};
154
+ let lessonVersion: string | null = null;
155
+
156
+ try {
157
+ const lessonResp = await fetch(lessonCfgUrl);
158
+ if (!lessonResp.ok) throw new Error("Lesson config.json missing");
159
+
160
+ // Check for empty file (0 bytes)
161
+ const text = await lessonResp.text();
162
+ if (text.trim().length > 0) {
163
+ lessonCfg = JSON.parse(text);
164
+ } else {
165
+ console.warn("Lesson config.json is EMPTY → falling back to latest version");
166
+ }
167
+
168
+ lessonVersion = lessonCfg.code_version;
169
+ console.log(`%c USING THE VERSION FOLDER--> ${lessonVersion} `,"color: #3bffe8ff; background:#d32f2f; font-size: 15px; font-weight: bold; padding: 6px 10px; border-radius: 4px;");
170
+
171
+ } catch (parseErr) {
172
+ console.warn("Lesson config.json invalid or unreadable → fallback to latest version");
173
+ lessonVersion = null;
174
+ }
126
175
 
127
- else if (this.codeFolderPath) {
128
- const cleanBase = this.baseUrl.replace(/\/+$/, "");
129
- const cfgUrl = `${cleanBase}/config.json`;
176
+ // Normalize invalid versions
177
+ if (!lessonVersion || typeof lessonVersion !== "string" || lessonVersion.trim() === "") {
178
+ console.warn("Lesson has NO valid codeVersion → using latest version in code-folder-path");
179
+ lessonVersion = null;
180
+ }
130
181
 
131
- try {
132
- const res = await fetch(cfgUrl);
133
-
134
- if (!res.ok) {
135
- console.warn("config.json not found. Skipping versioning and continuing...");
136
- throw new Error("config.json fetch failed");
137
- }
138
- else {
139
- const cfg = await res.json();
140
- const version = cfg.codeVersion;
141
-
142
- if (!version) {
143
- console.warn("config.json missing codeVersion. Skipping versioning. Falling back to npm package lido-player...");
144
- throw new Error("codeVersion missing in config.json");
145
- } else {
146
- // --- Version exists: try to load versioned folder ---
147
- const codePath = this.codeFolderPath.replace(/\/+$/, "");
148
- const versionFolder = `${codePath}/${version}`;
149
-
150
- const esmUrl = `${versionFolder}/lido-player.esm.js`;
151
- const noModuleUrl = `${versionFolder}/lido-player.js`;
152
-
153
- // Check if versioned ESM exists
154
- const headCheck = await fetch(esmUrl, { method: "HEAD" });
155
-
156
- if (!headCheck.ok) {
157
- console.warn(`Version folder found but lido-player.esm.js missing: ${esmUrl}`);
158
- } else {
159
- // --- Load versioned scripts (SUCCESS CASE) ---
160
- const scriptEsm = document.createElement("script");
161
- scriptEsm.type = "module";
162
- scriptEsm.src = esmUrl;
163
- document.head.appendChild(scriptEsm);
164
-
165
- const scriptNoModule = document.createElement("script");
166
- scriptNoModule.setAttribute("nomodule", "");
167
- scriptNoModule.src = noModuleUrl;
168
- document.head.appendChild(scriptNoModule);
169
-
170
- this.scriptsInjected = true;
171
- console.debug("Loaded version from config.json:", versionFolder);
172
- return; // return when version successfully loaded
173
- }
174
- }
182
+ // 2️⃣ Load version list from code-folder-path/config.json
183
+ const codeCfgUrl = `${this.codeFolderPath.replace(/\/+$/, '')}/config.json`;
184
+ const codeResp = await fetch(codeCfgUrl);
185
+ if (!codeResp.ok) throw new Error("Code-folder config.json missing");
186
+
187
+ const codeCfg = await codeResp.json();
188
+ const availableVersions: string[] = codeCfg.versions || [];
189
+
190
+ if (!availableVersions.length) {
191
+ throw new Error("No versions listed in code-folder config.json");
175
192
  }
176
- } catch (e) {
177
- console.error("Failed to read config.json. Skipping versioning...", e);
178
- this.fallbackNpmImport();
179
- }
180
- // If we reach this point, version loading FAILED → continue to final else
181
- }
182
193
 
183
- else {
184
- // Otherwise, fallback to the npm package
185
- console.warn(`Could not find remote scripts at "${scriptCheckUrl}". Falling back to npm package "lido-player"...`);
194
+ // 3️⃣ Compute selected version
195
+ let selectedVersion: string | undefined = null;
196
+
197
+ if (lessonVersion) {
198
+ selectedVersion = availableVersions.find(v => v.includes(lessonVersion));
199
+ }
200
+
201
+ // Fallback: use latest version
202
+ if (!selectedVersion) {
203
+ selectedVersion = availableVersions[availableVersions.length - 1];
204
+ console.log(`%c USING THE LATEST VERSION FOLDER-> ${selectedVersion} `,"color: #3bffe8ff; background:#d32f2f; font-size: 15px; font-weight: bold; padding: 6px 10px; border-radius: 4px;");
205
+ }
206
+
207
+ // 4️⃣ Inject scripts
208
+ const versionDir = `${this.codeFolderPath}/${selectedVersion}`;
209
+ const esmUrl = `${versionDir}/lido-player.esm.js`;
210
+ const noModuleUrl = `${versionDir}/lido-player.js`;
211
+
212
+ // Check if version folder exists
213
+ const headCheck = await fetch(esmUrl, { method: "HEAD" });
214
+ if (!headCheck.ok) throw new Error(`Versioned script missing: ${esmUrl}`);
215
+
216
+ // Inject main module file
217
+ const scriptEsm = document.createElement("script");
218
+ scriptEsm.type = "module";
219
+ scriptEsm.src = esmUrl;
220
+ document.head.appendChild(scriptEsm);
221
+
222
+ // Inject fallback nomodule script
223
+ const scriptNoModule = document.createElement("script");
224
+ scriptNoModule.setAttribute("nomodule", "");
225
+ scriptNoModule.src = noModuleUrl;
226
+ document.head.appendChild(scriptNoModule);
227
+
228
+ this.scriptsInjected = true;
229
+ console.debug("Loaded Lido version from:", versionDir);
230
+
231
+ }catch (err) {
232
+ console.warn("Failed to load versioned scripts, falling back to npm:", err);
233
+ this.fallbackNpmImport();
234
+ }
235
+ } catch (err) {
236
+ console.warn("Failed loading scripts → fallback to npm:", err);
186
237
  this.fallbackNpmImport();
187
238
  }
239
+ return;
240
+ }
241
+ this.fallbackNpmImport();
188
242
  }
189
243
 
190
- /**
191
- * Synchronously checks if a file exists via HTTP HEAD request.
192
- * Returns true if status is 2xx, false otherwise.
193
- */
194
- private doesFileExistSync(url: string): boolean {
195
- let exists = false;
196
- try {
197
- const xhr = new XMLHttpRequest();
198
- xhr.open('HEAD', url, false); // false = synchronous
199
- xhr.send(null);
200
- exists = xhr.status >= 200 && xhr.status < 300;
201
- } catch (err) {
202
- console.warn('Synchronous HEAD request failed for:', url, err);
203
- }
204
- return exists;
244
+ /**
245
+ * Checks if a file truly exists (not a dev-server fallback).
246
+ * Ensures:
247
+ * - HTTP HEAD returns 2xx
248
+ * - responseURL matches the requested URL
249
+ */
250
+ private doesFileExistSync(url: string): boolean {
251
+ try {
252
+ const xhr = new XMLHttpRequest();
253
+ xhr.open("HEAD", url, false); // synchronous
254
+ xhr.send();
255
+
256
+ const statusOk = xhr.status >= 200 && xhr.status < 300;
257
+
258
+ if (!statusOk) return false;
259
+
260
+ // Detect fallback HTML responses (common when folder/file is missing)
261
+ const contentType = xhr.getResponseHeader("Content-Type") || "";
262
+
263
+ const isHtmlFallback = contentType.includes("text/html");
264
+
265
+ return !isHtmlFallback;
266
+ } catch (err) {
267
+ console.warn("File existence check failed for:", url, err);
268
+ return false;
205
269
  }
270
+ }
271
+
206
272
 
207
273
  /**
208
274
  * Fallback approach: dynamically import the "lido-player/loader" module,
@@ -231,7 +297,6 @@ export class LidoStandalone {
231
297
  }
232
298
 
233
299
  // If xmlPath is not explicitly provided, default to `index.xml` in baseUrl
234
- if (!this.xmlPath) {
235
300
  if (this.baseUrl) {
236
301
  const cleanBase = this.baseUrl.replace(/\/+$/, '');
237
302
  this.xmlPath = `${cleanBase}/index.xml`;
@@ -239,7 +304,6 @@ export class LidoStandalone {
239
304
  } else {
240
305
  return;
241
306
  }
242
- }
243
307
 
244
308
  try {
245
309
  const xhr = new XMLHttpRequest();
@@ -268,7 +332,8 @@ export class LidoStandalone {
268
332
  * This ensures the custom elements are defined before usage.
269
333
  */
270
334
 
271
- return <lido-home common-audio-path={this.commonAudioPath} initial-index={this.initialIndex} canplay={this.canplay} height={this.height} xml-data={this.localXmlData} base-url={this.xmlBaseUrl} code-folder-path={this.codeFolderPath}></lido-home>;
335
+ const lang = this.language || 'en';
336
+ return <lido-home common-audio-path={this.commonAudioPath} initial-index={this.initialIndex} canplay={this.canplay} height={this.height} lang={lang} xml-data={this.localXmlData} base-url={this.xmlBaseUrl} code-folder-path={this.codeFolderPath} zip-url={this.zipUrl}></lido-home>;
272
337
  }
273
338
 
274
339
 
@@ -31,8 +31,10 @@ and calls defineCustomElements(...) to register <lido-home>.
31
31
  | `commonAudioPath` | `common-audio-path` | | `string` | `undefined` |
32
32
  | `height` | `height` | The height prop to pass to <lido-home>. Defaults to "75vh". | `string` | `'75vh'` |
33
33
  | `initialIndex` | `initial-index` | The initial index to pass down to <lido-home>. Defaults to 0. | `number` | `0` |
34
+ | `language` | `language` | The language prop to pass to <lido-home>. | `string` | `undefined` |
34
35
  | `xmlData` | `xml-data` | Optional prop for directly providing XML data instead of fetching. | `string` | `undefined` |
35
36
  | `xmlPath` | `xml-path` | If provided, we'll fetch this XML path once and pass the loaded string to <lido-home>'s `xml-data` attribute. | `string` | `undefined` |
37
+ | `zipUrl` | `zip-url` | To pass zip file directly to <lido-home> as its attribute. | `string` | `undefined` |
36
38
 
37
39
 
38
40
  ----------------------------------------------
@@ -41,6 +41,10 @@ export namespace Components {
41
41
  * The initial index to pass down to <lido-home>. Defaults to 0.
42
42
  */
43
43
  "initialIndex": number;
44
+ /**
45
+ * The language prop to pass to <lido-home>.
46
+ */
47
+ "language"?: string;
44
48
  /**
45
49
  * Optional prop for directly providing XML data instead of fetching.
46
50
  */
@@ -49,6 +53,10 @@ export namespace Components {
49
53
  * If provided, we'll fetch this XML path once and pass the loaded string to <lido-home>'s `xml-data` attribute.
50
54
  */
51
55
  "xmlPath"?: string;
56
+ /**
57
+ * To pass zip file directly to <lido-home> as its attribute.
58
+ */
59
+ "zipUrl"?: string;
52
60
  }
53
61
  }
54
62
  declare global {
@@ -111,6 +119,10 @@ declare namespace LocalJSX {
111
119
  * The initial index to pass down to <lido-home>. Defaults to 0.
112
120
  */
113
121
  "initialIndex"?: number;
122
+ /**
123
+ * The language prop to pass to <lido-home>.
124
+ */
125
+ "language"?: string;
114
126
  /**
115
127
  * Optional prop for directly providing XML data instead of fetching.
116
128
  */
@@ -119,6 +131,10 @@ declare namespace LocalJSX {
119
131
  * If provided, we'll fetch this XML path once and pass the loaded string to <lido-home>'s `xml-data` attribute.
120
132
  */
121
133
  "xmlPath"?: string;
134
+ /**
135
+ * To pass zip file directly to <lido-home> as its attribute.
136
+ */
137
+ "zipUrl"?: string;
122
138
  }
123
139
  interface IntrinsicElements {
124
140
  "lido-standalone": LidoStandalone;