scorm-player 1.2.3 → 1.2.4

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 (2) hide show
  1. package/README.md +114 -44
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -4,11 +4,15 @@ A lightweight SCORM 2004 unpacker + manifest parser + storage adapter system.
4
4
 
5
5
  This package allows you to:
6
6
 
7
- - Upload SCORM 2004 ZIP packages
8
- - Unpack them server-side (Node.js, Next.js server actions)
9
- - Parse imsmanifest.xml (using a Node-compatible DOM parser)
10
- - Save unpacked files to any storage (Supabase included)
11
- - Render SCORM content inside a React <ScormPlayer /> component
7
+ Upload SCORM 2004 ZIP packages
8
+
9
+ Unpack them server-side (Node.js, Next.js server actions)
10
+
11
+ Parse imsmanifest.xml (using a Node-compatible DOM parser)
12
+
13
+ Save unpacked files to any storage (Supabase included)
14
+
15
+ Render SCORM content inside a React <ScormPlayer /> component or as a full-page course
12
16
 
13
17
  ## 🚀 Features
14
18
 
@@ -29,7 +33,7 @@ npm install scorm-player
29
33
 
30
34
  The package requires:
31
35
 
32
- - react >= 18
36
+ react >= 18
33
37
 
34
38
  React is declared as a peer dependency, so it will use whatever version the project already has.
35
39
 
@@ -60,54 +64,81 @@ import { unpackSCORM, parseManifest, SupabaseAdapter } from "scorm-player";
60
64
  import { ScormPlayer } from "scorm-player";
61
65
  ```
62
66
 
63
- ## 🧭 Usage — Upload SCORM Package (Next.js Server Action)
67
+ ## 🧭 Usage — Upload a SCORM Package (Next.js Server Action)
64
68
 
65
- ### Client Component (upload button)
69
+ ### Client Component (Upload Button + Get Launch Link)
66
70
 
67
71
  ```typescript
68
72
  "use client";
69
73
 
70
74
  import { useState } from "react";
71
75
  import { uploadSCORMCourse } from "./actions/uploadSCORMCourse";
76
+ import { ScormPlayer } from "scorm-player";
72
77
 
73
78
  export default function ScormPage() {
74
79
  const [file, setFile] = useState<File | null>(null);
80
+ const [link, setLink] = useState<string>("");
81
+
82
+ const handleUpload = async () => {
83
+ if (!file) return;
84
+
85
+ // Get the SCORM launch link after uploading
86
+ const launchLink = await uploadSCORMCourse(file, "tests");
87
+ setLink(launchLink);
88
+ console.log("SCORM launch link:", launchLink);
89
+ };
75
90
 
76
91
  return (
77
- <div>
78
- <input
79
- type='file'
80
- onChange={(e) => setFile(e.target.files?.[0] || null)}
81
- />
82
- <button onClick={() => file && uploadSCORMCourse(file)}>
83
- Upload
84
- </button>
85
- </div>
92
+ <>
93
+ <div>
94
+ <input
95
+ type='file'
96
+ onChange={(e) => setFile(e.target.files?.[0] || null)}
97
+ />
98
+ <button onClick={handleUpload}>Upload</button>
99
+ </div>
100
+
101
+ {/* Embed SCORM in an iframe */}
102
+ {link && (
103
+ <ScormPlayer
104
+ launchUrl={link}
105
+ saveProgress={(data) =>
106
+ console.log("SCORM Progress:", data)
107
+ }
108
+ />
109
+ )}
110
+ </>
86
111
  );
87
112
  }
88
113
  ```
89
114
 
90
- ### Server Action (unpack + save SCORM)
115
+ ### Server Action (Unpack + Save SCORM)
91
116
 
92
117
  ```typescript
93
118
  "use server";
94
119
 
95
120
  import { unpackSCORM, parseManifest, SupabaseAdapter } from "scorm-player";
96
121
 
97
- export async function uploadSCORMCourse(file: File) {
98
- const arrayBuffer = await file.arrayBuffer();
99
- const buffer = Buffer.from(arrayBuffer);
100
-
122
+ export async function uploadSCORMCourse(
123
+ file: File,
124
+ baseFolder: string = "course"
125
+ ) {
126
+ const buffer = Buffer.from(await file.arrayBuffer());
101
127
  const { files, manifestXml } = await unpackSCORM(buffer);
102
- const launchUrl = parseManifest(manifestXml);
128
+
129
+ const launchPath = parseManifest(manifestXml); // path to index.html
103
130
 
104
131
  const adapter = new SupabaseAdapter(
105
- process.env.SUPABASE_URL!,
106
- process.env.SUPABASE_KEY!,
107
- "courses"
132
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
133
+ process.env.NEXT_PUBLIC_SUPABASE_SERVICE_KEY!,
134
+ baseFolder
108
135
  );
109
136
 
110
- await adapter.uploadFolder("courses", files);
137
+ // Upload SCORM files and get a unique folder
138
+ const uniqueFolder = await adapter.uploadFolder(files, baseFolder);
139
+
140
+ // Form the full launch URL via API route
141
+ const launchUrl = `/api/scorm/${uniqueFolder}/${launchPath}`;
111
142
 
112
143
  return launchUrl;
113
144
  }
@@ -115,45 +146,84 @@ export async function uploadSCORMCourse(file: File) {
115
146
 
116
147
  ## 🖥️ Displaying SCORM Content
117
148
 
149
+ ### 1️⃣ In an iframe (embedded mode)
150
+
118
151
  ```typescript
119
152
  import { ScormPlayer } from "scorm-player";
120
153
 
121
154
  export default function PlayerPage() {
122
- return <ScormPlayer launchUrl='courses/index.html' />;
155
+ const launchUrl = "/api/scorm/abc123/index.html";
156
+
157
+ return (
158
+ <ScormPlayer
159
+ launchUrl={launchUrl}
160
+ saveProgress={(data) => console.log("SCORM Progress:", data)}
161
+ />
162
+ );
123
163
  }
124
164
  ```
125
165
 
126
- The component uses an <iframe /> to show SCORM content.
166
+ ### 2️⃣ Full-page mode (open in a separate tab)
127
167
 
128
- ## 🗃️ Supabase Storage Adapter
168
+ Simply redirect the user to the SCORM API route:
129
169
 
130
- Uploads all extracted SCORM files:
170
+ ```typescript
171
+ "use client";
172
+ import { useEffect } from "react";
173
+
174
+ export default function LaunchScormPage({
175
+ searchParams,
176
+ }: {
177
+ searchParams: { launch: string };
178
+ }) {
179
+ useEffect(() => {
180
+ if (searchParams.launch) {
181
+ // Add query param ?mode=page for full-page mode
182
+ window.location.href = `${searchParams.launch}?mode=page`;
183
+ }
184
+ }, [searchParams.launch]);
185
+
186
+ return <p>Loading SCORM course...</p>;
187
+ }
188
+ ```
189
+
190
+ Usage example:
131
191
 
132
192
  ```typescript
133
- const adapter = new SupabaseAdapter(SUPABASE_URL, SUPABASE_KEY, "folderName");
193
+ // After uploading
194
+ const launchLink = await uploadSCORMCourse(file, "tests");
195
+
196
+ // Embedded mode
197
+ <ScormPlayer launchUrl={launchLink} saveProgress={...} />
134
198
 
135
- await adapter.uploadFolder("folderName", files);
199
+ // Full-page mode
200
+ window.open(`${launchLink}?mode=page`, "_blank");
136
201
  ```
137
202
 
138
- You can also write your own adapters (S3, GCP, local FS, etc.).
203
+ In full-page mode, no additional Next.js component is required the SCORM content renders directly through the /api/scorm/... route.
204
+
205
+ ## 🗃️ Supabase Storage Adapter
206
+
207
+ ```typescript
208
+ const adapter = new SupabaseAdapter(SUPABASE_URL, SUPABASE_KEY, "folderName");
209
+ await adapter.uploadFolder(files, "folderName");
210
+ ```
211
+
212
+ You can also write your own adapters for S3, GCP, local FS, etc.
139
213
 
140
214
  ## 🧩 API Reference
141
215
 
142
- - `unpackSCORM(zipData: Buffer | Uint8Array)` - Unpacks a SCORM ZIP file into a dictionary of files.
143
- - `parseManifest(manifestXml: string)` - Locates the SCORM launch URL from imsmanifest.xml.
144
- - `SupabaseAdapter` - Uploads unpacked files into Supabase Storage.
145
- - `<ScormPlayer launchUrl="..." />` - Renders SCORM content inside an iframe.
216
+ - `unpackSCORM(zipData: Buffer | Uint8Array)` Unpacks a SCORM ZIP file into a dictionary of files.
217
+ - `parseManifest(manifestXml: string)` Locates the SCORM launch URL from imsmanifest.xml.
218
+ - `SupabaseAdapter` Uploads unpacked files into Supabase Storage.
219
+ - `<ScormPlayer launchUrl="..." />` Renders SCORM content inside an iframe.
146
220
 
147
221
  ## 🛠️ Requirements
148
222
 
149
223
  - Node.js 18+
150
- - React 18 or newer
151
- - Next.js (optional but supported)
224
+ - React 18+
225
+ - Next.js 15+ (App Router)
152
226
 
153
227
  ## 📄 License
154
228
 
155
229
  MIT License.
156
-
157
- ## 🎉 Done
158
-
159
- Your SCORM Player is ready to use.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scorm-player",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "SCORM 2004 player, unpacker and manifest parser for Node.js / Next.js with storage adapters and React iframe renderer.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",