### Start Development Server
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/PLAYER_SUMMARY.md
Commands to navigate to the example directory and start the development server.
```bash
# Start development server
cd examples/react-native-offline
npm start
# Navigate to player
# URL: /player/minimal-test
```
--------------------------------
### Install Dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/QUICKSTART.md
Navigate to the example directory and install project dependencies using npm.
```bash
cd examples/react-native-offline
npm install
```
--------------------------------
### Start the React Native App
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/PLAYER_QUICK_START.md
Instructions to start the React Native application from the examples directory. After starting, navigate to the player.
```bash
# Start the app
cd examples/react-native-offline
npm start
# Then navigate to: /player/minimal-test
```
--------------------------------
### Implement Complete SCORM 2004 Setup
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/getting-started/quick-start.md
A full example demonstrating API configuration, window attachment, and event listeners.
```javascript
import { Scorm2004API } from 'scorm-again/scorm2004';
// Configure the API
const settings = {
autocommit: true,
autocommitSeconds: 60,
lmsCommitUrl: 'https://your-lms.com/api/scorm/commit',
logLevel: 'INFO'
};
// Create and attach to window
const api = new Scorm2004API(settings);
window.API_1484_11 = api;
// Listen for events (optional but recommended)
api.on('Initialize', () => {
console.log('SCORM content initialized');
});
api.on('SetValue.cmi.completion_status', (cmiElement, value) => {
console.log('Completion status changed to:', value);
});
api.on('Terminate', () => {
console.log('SCORM session terminated');
});
// The SCORM content will now be able to communicate with the LMS
```
--------------------------------
### Run scorm-again Demos Locally
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/player-wrapper-guide.md
Commands to clone, install, build, and start the local demonstration server.
```bash
# Clone and install
git clone https://github.com/jcputney/scorm-again.git
cd scorm-again
npm install
# Build the library
npm run build
# Navigate to demos
cd demos/player-wrapper
# Start demo server
npm start
# Open in browser
# SCORM 1.2: http://localhost:3000/scorm12-multi-sco/
# SCORM 2004 Simple: http://localhost:3000/scorm2004-simple/
# SCORM 2004 Sequenced: http://localhost:3000/scorm2004-sequenced/
```
--------------------------------
### Parent Frame (LMS) Setup Example
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/cross-frame-communication.md
Example of how to set up the CrossFrameLMS in the parent LMS frame.
```APIDOC
## Parent Frame (LMS) Setup Example
### Description
This example demonstrates initializing the SCORM API and wrapping it with `CrossFrameLMS` in the LMS parent frame, along with embedding the content iframe.
### Code
```html
```
```
--------------------------------
### Complete SCORM 2004 Sequencing Configuration Example
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/sequencing.md
A full example demonstrating the setup of SCORM 2004 sequencing, including activity tree, various rules (pre-condition, exit, post-condition), and sequencing controls. This configuration defines a course structure and its navigation/completion logic.
```javascript
import { Scorm2004API } from "scorm-again";
const api = new Scorm2004API({
// Other settings...
sequencing: {
activityTree: {
id: "root",
title: "Course",
children: [
{
id: "module1",
title: "Module 1",
children: [
{
id: "lesson1",
title: "Lesson 1",
},
{
id: "lesson2",
title: "Lesson 2",
},
],
},
{
id: "module2",
title: "Module 2",
children: [
{
id: "lesson3",
title: "Lesson 3",
},
{
id: "lesson4",
title: "Lesson 4",
},
],
},
],
},
sequencingRules: {
preConditionRules: [
{
action: "skip",
conditionCombination: "all",
conditions: [
{
condition: "completed",
operator: "not",
},
],
},
],
exitConditionRules: [
{
action: "exitParent",
conditions: [
{
condition: "completed",
},
],
},
],
postConditionRules: [
{
action: "continue",
conditions: [
{
condition: "completed",
},
],
},
],
},
sequencingControls: {
enabled: true,
choiceExit: true,
flow: true,
forwardOnly: false,
useCurrentAttemptObjectiveInfo: true,
useCurrentAttemptProgressInfo: true,
preventActivation: false,
constrainChoice: false,
rollupObjectiveSatisfied: true,
rollupProgressCompletion: true,
objectiveMeasureWeight: 1.0,
},
rollupRules: {
rules: [
{
action: "completed",
consideration: "all",
conditions: [
{
condition: "completed",
},
],
},
{
action: "satisfied",
consideration: "all",
conditions: [
{
condition: "satisfied",
},
],
},
],
},
},
});
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/README.md
Installs all necessary dependencies for the project. This command must be run in the repository directory before starting development.
```bash
npm install
```
--------------------------------
### Child Frame (Content) Setup Example
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/cross-frame-communication.md
Example of how to set up the CrossFrameAPI in the child content frame.
```APIDOC
## Child Frame (Content) Setup Example
### Description
This example shows how to initialize the `CrossFrameAPI` in the content's iframe, allowing it to interact with the SCORM API proxied by the parent LMS.
### Code
```html
```
```
--------------------------------
### Set up Local HTTP Server with NanoHTTPD
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/mobile/android-native.md
Implement a local HTTP server using NanoHTTPD to serve SCORM content, avoiding CORS issues with file:// URLs. This example starts the server and constructs a course URL.
```kotlin
import fi.iki.elonen.NanoHTTPD
class LocalServer(port: Int, private val rootDir: File) : NanoHTTPD(port) {
override fun serve(session: IHTTPSession): Response {
val uri = session.uri
val file = File(rootDir, uri)
val mimeType = getMimeTypeForFile(uri)
return newFixedLengthResponse(Response.Status.OK, mimeType, FileInputStream(file), file.length())
}
}
val server = LocalServer(0, documentsDir)
server.start()
val courseUrl = "http://127.0.0.1:${server.listeningPort}/courses/${courseId}/index.html"
```
--------------------------------
### Install Dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/README.md
Run this command to install all required project dependencies.
```bash
yarn
```
--------------------------------
### Event Configuration Example
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/integration-guide.md
Example of how to initialize the Scorm2004API with various event listeners for managing activity delivery, navigation, course completion, and debugging.
```APIDOC
## Event Configuration Example
### Description
This example demonstrates how to configure event listeners for the `Scorm2004API` to handle key sequencing events such as activity delivery, navigation updates, rollup completion, and session end.
### Method
Initialization of `Scorm2004API` with `sequencing` options.
### Endpoint
N/A (Client-side JavaScript configuration)
### Parameters
#### Request Body
- **`sequencing`** (object) - Configuration object for sequencing.
- **`activityTree`** (object) - The structure defining the course activities.
- **`eventListeners`** (object) - An object containing callback functions for various sequencing events:
- **`onActivityDelivery`** (function) - Called when an activity is ready for delivery.
- **`onNavigationValidityUpdate`** (function) - Called when navigation button validity changes.
- **`onRollupComplete`** (function) - Called when a rollup process completes.
- **`onSequencingSessionEnd`** (function) - Called when the sequencing session ends.
- **`onSequencingDebug`** (function) - Called for debug messages during sequencing.
### Request Example
```javascript
const api = new Scorm2004API({
sequencing: {
activityTree: activityTree,
eventListeners: {
onActivityDelivery: (activity) => {
console.log(`Launching: ${activity.id}`);
launchContent(activity);
},
onNavigationValidityUpdate: (data) => {
setNavEnabled('continue', data.validRequests.includes('continue'));
setNavEnabled('previous', data.validRequests.includes('previous'));
},
onRollupComplete: (activity) => {
if (activity.id === 'root') {
console.log('Course rollup complete');
updateCourseStatus(activity);
}
},
onSequencingSessionEnd: (data) => {
console.log(`Session ended: ${data.reason}`);
if (data.reason === 'exitAll') {
showCourseCompletionScreen();
}
},
onSequencingDebug: (data) => {
console.debug('[Sequencing]', data.message, data.context);
}
}
}
});
```
### Response
N/A (This is a configuration example, not an API call with a direct response.)
```
--------------------------------
### Start Local Development Server
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/README.md
Launches a local development server with live reloading enabled.
```bash
yarn start
```
--------------------------------
### Install Dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/developer/development-workflow.md
Install the project dependencies using npm.
```bash
npm install
```
--------------------------------
### Clone and Setup Repository
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/developer/development-workflow.md
Initial commands to clone the repository and add the upstream remote for synchronization.
```bash
git clone https://github.com/YOUR-USERNAME/scorm-again.git
cd scorm-again
```
```bash
git remote add upstream https://github.com/jcputney/scorm-again.git
```
--------------------------------
### Implement LMS Launch Page
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/cross-frame-communication.md
Complete example of setting up the parent page with the Scorm2004API and CrossFrameLMS bridge.
```html
LMS - Course Launch
Course: Introduction to SCORM
Progress: Not started
```
--------------------------------
### Start Development Server
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/QUICKSTART.md
Initiate the React Native development server to run the application.
```bash
npm start
```
--------------------------------
### App Navigation Setup
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/mobile/react-native.md
Example of how to integrate the SCORM player component into your React Navigation stack. Ensure the 'ScormPlayerScreen' path is correct.
```jsx
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import ScormPlayerScreen from './src/screens/ScormPlayerScreen';
import HomeScreen from './src/screens/HomeScreen';
const Stack = createStackNavigator();
export default function App() {
return (
);
}
```
--------------------------------
### Start Local Server with GCDWebServer (Swift)
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/mobile/kotlin-multiplatform.md
Initializes and starts a local HTTP server using GCDWebServer to serve local content. The server binds to localhost on a random available port.
```swift
import GCDWebServer
class LocalContentServer {
private let server = GCDWebServer()
func start(rootPath: String) -> Int {
server.addGETHandler(
forBasePath: "/",
directoryPath: rootPath,
indexFilename: "index.html",
cacheAge: 0,
allowRangeRequests: true
)
try? server.start(options: [
GCDWebServerOption_Port: 0,
GCDWebServerOption_BindToLocalhost: true
])
return Int(server.port)
}
func stop() {
server.stop()
}
var baseURL: String {
return "http://localhost:\(server.port)"
}
}
```
--------------------------------
### Include Library in HTML
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/developer/development-workflow.md
Example of how to include the built library in an HTML file.
```html
```
--------------------------------
### Install Fetch Polyfill via npm
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/getting-started/installation.md
Install the whatwg-fetch package using npm for use in module-based projects.
```bash
npm install whatwg-fetch
```
--------------------------------
### Build and Development Commands
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/PLAYER_SETUP.md
Commands for copying assets, starting the development server, and navigating to test courses.
```bash
cp dist/scorm2004.min.js examples/react-native-offline/assets/scorm-again/
```
```bash
cd examples/react-native-offline
npm start
```
```text
/player/minimal-test
```
```bash
cp dist/scorm12.min.js examples/react-native-offline/assets/scorm-again/
```
--------------------------------
### Install NetInfo Dependency
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/QUICKSTART.md
If NetInfo is not available, install the community package and rebuild the project.
```bash
npm install @react-native-community/netinfo
npx expo prebuild --clean
```
--------------------------------
### Install via Package Managers
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/getting-started/installation.md
Use npm or yarn to add the library to your project dependencies.
```bash
npm install scorm-again
```
```bash
yarn add scorm-again
```
--------------------------------
### Install Scorm-Again Package
Source: https://github.com/jcputney/scorm-again/blob/master/README.md
Install the scorm-again package using npm or yarn.
```sh
npm install scorm-again
# or
yarn add scorm-again
```
--------------------------------
### Install React Native dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/mobile/react-native.md
Install the core libraries required for WebView, file system access, and network connectivity.
```bash
# Install core dependencies
npm install --save react-native-webview react-native-fs react-native-device-info react-native-zip-archive
# For handling network connectivity
npm install --save @react-native-community/netinfo
# For external storage access
npm install --save react-native-permissions react-native-blob-util
```
--------------------------------
### Run Project Tests
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/PROJECT_STATUS.md
Execute these commands to install dependencies, prebuild native folders, and run the project on iOS or Android.
```bash
cd examples/react-native-offline
npm install # May require fixing npm cache permissions
npx expo prebuild
npm run ios # or npm run android
```
--------------------------------
### Install React Native Static Server
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/offline/troubleshooting.md
Install the dependency required for serving local files over HTTP in React Native.
```bash
npm install @dr.pogodin/react-native-static-server
```
--------------------------------
### Start Local HTTP Server in iOS (Swift)
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/offline/troubleshooting.md
Configure a GCDWebServer instance to serve files from the documents directory.
```swift
import GCDWebServer
let webServer = GCDWebServer()
webServer.addGETHandler(forBasePath: "/", directoryPath: documentsPath, indexFilename: nil, cacheAge: 0, allowRangeRequests: true)
webServer.start(withPort: 0, bonjourName: nil)
let origin = "http://127.0.0.1:\(webServer.port)"
```
--------------------------------
### Start Local HTTP Server in Android (Kotlin)
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/offline/troubleshooting.md
Implement a custom NanoHTTPD server to serve files from the local filesystem.
```kotlin
import fi.iki.elonen.NanoHTTPD
class LocalServer(port: Int, private val rootDir: File) : NanoHTTPD(port) {
override fun serve(session: IHTTPSession): Response {
val uri = session.uri
val file = File(rootDir, uri)
return newFixedLengthResponse(Response.Status.OK, getMimeType(uri), FileInputStream(file), file.length())
}
}
val server = LocalServer(0, documentsDir)
server.start()
val origin = "http://127.0.0.1:${server.listeningPort}"
```
--------------------------------
### Run Integration Tests
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/developer/testing.md
Commands to install dependencies and execute browser-based integration tests.
```bash
npm install
```
```bash
npm run test:integration
```
--------------------------------
### Setup and Run Integration Tests Locally
Source: https://github.com/jcputney/scorm-again/blob/master/AGENTS.md
Commands to set up and run integration tests locally for debugging purposes.
```bash
npm run test:integration:setup
```
```bash
npm run test:integration:server
```
--------------------------------
### Start Local HTTP Server in Flutter
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/offline/troubleshooting.md
Use the shelf package to serve static files from a local directory.
```dart
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_static/shelf_static.dart';
final handler = createStaticHandler('/path/to/documents');
final server = await shelf_io.serve(handler, '127.0.0.1', 0);
final origin = 'http://127.0.0.1:${server.port}';
```
--------------------------------
### Install AsyncStorage Dependency
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/SETTINGS_SCREEN.md
Run these commands if encountering import errors related to AsyncStorage.
```bash
npm install @react-native-async-storage/async-storage
expo prebuild --clean
```
--------------------------------
### Initialize Scorm12API
Source: https://github.com/jcputney/scorm-again/blob/master/docs/lms-integration/data-requirements-quick-reference.md
Configuration example for the Scorm12API, including commit URLs, auto-commit settings, and HTTP options.
```javascript
new Scorm12API({
// Required
lmsCommitUrl: "/api/scorm/commit",
// Auto-commit
autocommit: true,
autocommitSeconds: 60,
// Behavior
mastery_override: true, // Auto pass/fail from mastery_score
autoCompleteLessonStatus: true, // Auto-complete on LMSFinish
// Multi-SCO
globalStudentPreferences: true, // Share prefs across SCOs
// HTTP options
xhrHeaders: { "X-Custom": "value" },
xhrWithCredentials: false,
// Logging
logLevel: 4, // 1=DEBUG, 4=ERROR, 5=NONE
});
```
--------------------------------
### SCORM 2004 API Initialization
Source: https://github.com/jcputney/scorm-again/blob/master/docs/lms-integration/data-requirements-quick-reference.md
Example of initializing the SCORM 2004 API with various configuration options.
```APIDOC
## SCORM 2004 API Initialization
### Description
Initializes the SCORM 2004 API with required and optional settings.
### Method
`new Scorm2004API(options)`
### Parameters
#### Options Object
- **lmsCommitUrl** (string | boolean) - Required - URL for the commit endpoint. Set to `false` to disable commits.
- **autocommit** (boolean) - Optional - Automatically commit after SetValue calls. Defaults to `false`.
- **autocommitSeconds** (number) - Optional - Seconds between auto-commits when `autocommit` is enabled. Defaults to `10`.
- **sendFullCommit** (boolean) - Optional - Send all CMI data on commit vs only changed values. Defaults to `true`.
- **dataCommitFormat** (string) - Optional - Format for commit data: `"json"`, `"flattened"`, or `"params"`. Defaults to `"json"`.
- **commitRequestDataType** (string) - Optional - Content-Type header for commits. Defaults to `"application/json;charset=UTF-8"`.
- **autoProgress** (boolean) - Optional - Auto-advance through SCOs (SCORM 2004). Defaults to `false`.
- **logLevel** (LogLevel) - Optional - Logging verbosity: 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR, 5=NONE. Defaults to `4` (ERROR).
- **strict_errors** (boolean) - Optional - Strictly validate per SCORM spec. Defaults to `true`.
- **xhrHeaders** (object) - Optional - Custom headers for XHR requests. Defaults to `{}`.
- **xhrWithCredentials** (boolean) - Optional - Include cookies in cross-origin requests. Defaults to `false`.
- **fetchMode** (string) - Optional - Fetch mode: `"cors"`, `"no-cors"`, `"same-origin"`, `"navigate"`. Defaults to `"cors"`.
- **useBeaconInsteadOfFetch** (string) - Optional - Use sendBeacon: `"always"`, `"on-terminate"`, `"never"`. Defaults to `"never"`.
- **useAsynchronousCommits** (boolean) - Optional - Use async HTTP (not SCORM-compliant). Defaults to `false`.
- **throttleCommits** (boolean) - Optional - Throttle rapid commits (only with async). Defaults to `false`.
- **httpService** (IHttpService | null) - Optional - Custom HTTP service implementation. Defaults to `null`.
- **requestHandler** (function) - Optional - Transform commit data before sending. Defaults to identity function.
- **responseHandler** (function) - Optional - Handle fetch Response objects. Defaults to JSON parser.
- **xhrResponseHandler** (function) - Optional - Handle XHR responses. Defaults to JSON parser.
- **onLogMessage** (function) - Optional - Custom log handler. Defaults to console methods.
- **mastery_override** (boolean) - Optional - Override status based on mastery score. Defaults to `false`.
- **score_overrides_status** (boolean) - Optional - Score determines pass/fail automatically. Defaults to `false`.
- **completion_status_on_failed** (string) - Optional - Completion status when failed: `"completed"` or `"incomplete"`. Defaults to `"completed"`.
- **autoCompleteLessonStatus** (boolean) - Optional - Auto-complete lesson_status on finish. Defaults to `false`.
- **selfReportSessionTime** (boolean) - Optional - Allow content to set session_time directly. Defaults to `false`.
- **alwaysSendTotalTime** (boolean) - Optional - Always include total_time in commits. Defaults to `false`.
- **enableOfflineSupport** (boolean) - Optional - Enable offline data storage. Defaults to `false`.
- **courseId** (string) - Optional - Course identifier for offline storage. Defaults to `""`.
- **syncOnInitialize** (boolean) - Optional - Sync offline data on Initialize. Defaults to `true`.
- **syncOnTerminate** (boolean) - Optional - Sync offline data on Terminate. Defaults to `true`.
- **maxSyncAttempts** (number) - Optional - Maximum sync retry attempts. Defaults to `5`.
- **scoItemIds** (array) - Optional - Valid navigation targets.
- **globalObjectiveIds** (array) - Optional - Shared objectives.
- **sequencing** (object) - Optional - Sequencing configuration for sequenced courses.
- **activityTree** (object) - Required if `sequencing` is provided.
- **eventListeners** (object) - Optional.
- **onActivityDelivery** (function) - Callback for activity delivery.
- **onNavigationValidityUpdate** (function) - Callback for navigation validity updates.
- **onRollupComplete** (function) - Callback for rollup completion.
### Request Example
```javascript
new Scorm2004API({
lmsCommitUrl: "/api/scorm/commit",
autocommit: true,
autocommitSeconds: 60,
score_overrides_status: false,
autoProgress: false,
useBeaconInsteadOfFetch: "on-terminate",
autoPopulateCommitMetadata: true,
courseId: "course-123",
scoId: "sco-456",
scoItemIds: ["sco1", "sco2"],
globalObjectiveIds: ["global-obj"],
sequencing: {
activityTree: {},
eventListeners: {
onActivityDelivery: (activity) => console.log(activity),
onNavigationValidityUpdate: (data) => console.log(data),
onRollupComplete: (activity) => console.log(activity)
}
}
});
```
```
--------------------------------
### Params Data Output Examples
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/configuration/data-formats.md
Sample URL query string outputs for SCORM 1.2 and 2004.
```text
?cmi.core.student_id=12345&cmi.core.student_name=John%20Doe&cmi.core.lesson_location=page5&cmi.core.lesson_status=completed&cmi.core.score.raw=85&cmi.core.score.min=0&cmi.core.score.max=100&cmi.core.total_time=00:15:30&cmi.core.session_time=00:05:30&cmi.core.exit=suspend&cmi.suspend_data=bookmark%3Dchapter3%3Bprogress%3D75
```
```text
?cmi.learner_id=12345&cmi.learner_name=John%20Doe&cmi.location=page5&cmi.completion_status=completed&cmi.success_status=passed&cmi.score.scaled=0.85&cmi.score.raw=85&cmi.score.min=0&cmi.score.max=100&cmi.total_time=PT15M30S&cmi.session_time=PT5M30S&cmi.exit=suspend&cmi.suspend_data=bookmark%3Dchapter3%3Bprogress%3D75
```
--------------------------------
### Include via Local Script Tag
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/getting-started/installation.md
Reference local distribution files after installation or manual download.
```html
```
--------------------------------
### Install NetInfo Dependency
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/SETTINGS_SCREEN.md
Run these commands to resolve issues where network status incorrectly reports as offline.
```bash
npm install @react-native-community/netinfo
expo prebuild --clean
```
--------------------------------
### Start Local HTTP Server in React Native
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/offline/troubleshooting.md
Initialize a local server to serve SCORM content from the documents directory.
```typescript
import Server from '@dr.pogodin/react-native-static-server';
// Start server pointing to your documents directory
const server = new Server({
fileDir: '/path/to/documents',
port: 0, // Auto-select available port
hostname: '127.0.0.1',
stopInBackground: false,
});
const origin = await server.start();
// origin = 'http://127.0.0.1:PORT'
// Load course via HTTP instead of file://
const courseUrl = `${origin}/courses/${courseId}/index.html`;
```
--------------------------------
### TypeScript Usage Example
Source: https://github.com/jcputney/scorm-again/blob/master/README.md
Demonstrates importing SCORM API classes and the Settings type in TypeScript, and creating an instance with typed settings.
```typescript
import {Scorm12API, Scorm2004API} from 'scorm-again';
import {Settings} from 'scorm-again'; // Import types
// Create an instance with typed settings
const settings: Settings = {
autocommit: true,
logLevel: 'DEBUG'
};
const api = new Scorm2004API(settings);
```
--------------------------------
### Initialize Application
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/offline/post_condition_rules_demo.html
Sets up event listeners and initializes the demo on window load.
```javascript
// Initialize on load window.onload = () => { initializeDemo(); // Set up parameter visibility handler document.getElementById('postCondition').addEventListener('change', updateParameterVisibility); };
```
--------------------------------
### Import Specific API Example
Source: https://github.com/jcputney/scorm-again/blob/master/README.md
Import only the specific SCORM API you need to reduce bundle size, rather than the entire library.
```javascript
// Instead of
import {Scorm2004API} from 'scorm-again';
// Use
import {Scorm2004API} from 'scorm-again/scorm2004/min';
```
--------------------------------
### Configure Basic Activity Tree for Sequencing
Source: https://github.com/jcputney/scorm-again/blob/master/README.md
Define a hierarchical structure for activities within a SCORM package. This example shows a root activity with nested modules and lessons.
```javascript
sequencing = {
activityTree: {
id: 'root',
title: 'Course',
children: [
{
id: 'module1',
title: 'Module 1',
children: [
{
id: 'lesson1',
title: 'Lesson 1'
},
{
id: 'lesson2',
title: 'Lesson 2'
}
]
}
]
}
}
```
--------------------------------
### Bulk Initialize CMI Object with Flattened JSON in JavaScript
Source: https://github.com/jcputney/scorm-again/blob/master/README.md
Load multiple CMI properties using a flattened JSON object where keys represent the full CMI path. This method also requires initialization before the SCORM player starts.
```javascript
window.API_1484_11.loadFromFlattenedJSON(json);
```
```javascript
var json = {
"cmi.learner_id": "123",
"cmi.learner_name": "Bob The Builder",
"cmi.suspend_data": "viewed=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31|lastviewedslide=31|7#1##,3,3,3,7,3,3,7,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,11#0#b5e89fbb-7cfb-46f0-a7cb-758165d3fe7e=236~262~2542812732762722742772682802752822882852892872832862962931000~3579~32590001001010101010101010101001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001010010010010010010010010011010010010010010010010010010010010112101021000171000~236a71d398e-4023-4967-88fe-1af18721422d06passed6failed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105wrong110000000000000000000000000000000000~3185000000000000000000000000000000000000000000000000000000000000000000000000000000000~283~2191w11~21113101w41689~256~2100723031840~21007230314509062302670~2110723031061120000000000000000000~240~234531618~21601011000100000002814169400,#-1",
"cmi.interactions.0.id": "Question14_1",
"cmi.interactions.0.type": "choice",
"cmi.interactions.0.timestamp": "2018-08-26T11:05:21",
"cmi.interactions.0.weighting": "1",
"cmi.interactions.0.learner_response": "HTH",
"cmi.interactions.0.result": "wrong",
"cmi.interactions.0.latency": "PT2M30S",
"cmi.interactions.0.objectives.0.id": "Question14_1",
"cmi.interactions.0.objectives.0.correct_responses.0.pattern": "CPR"
};
```
--------------------------------
### Install AsyncStorage Dependency
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/QUICKSTART.md
If you encounter issues with AsyncStorage, install it and then rebuild the project.
```bash
npm install
npx expo prebuild --clean
```
--------------------------------
### Basic Multi-SCO Setup (SCORM 1.2)
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/use_cases/common_use_cases.md
Initializes a Scorm12API instance for a course, defines a data store for SCOs, and includes functions to launch SCOs and handle commit data.
```javascript
import { Scorm12API } from 'scorm-again';
// Create a single API instance for the course
const api = new Scorm12API({
lmsCommitUrl: '/api/scorm/commit',
autoPopulateCommitMetadata: true, // Automatically include SCO info in commits
courseId: 'course-12345',
});
// Storage for each SCO's data (typically from your database)
const scoDataStore = {
'sco-intro': { /* saved CMI data */ },
'sco-module1': { /* saved CMI data */ },
'sco-quiz': { /* saved CMI data */ },
};
/**
* Launch a specific SCO
* @param {string} scoId - The identifier for the SCO to launch
*/
function launchSCO(scoId) {
// Reset the API for the new SCO
api.reset({
scoId: scoId, // Identify which SCO is active
autoPopulateCommitMetadata: true,
});
// Pre-load any saved data for this SCO
const savedData = scoDataStore[scoId];
if (savedData) {
api.loadFromJSON(savedData);
}
// Launch the SCO content (implementation depends on your LMS)
loadSCOContent(scoId);
// The SCO will call LMSInitialize() when it loads
}
/**
* Handle commit data from a SCO
* This would typically be your server-side endpoint
*/
function handleCommit(commitObject) {
// commitObject now includes:
// - courseId: 'course-12345'
// - scoId: 'sco-module1' (whichever SCO is active)
// - learnerId: from cmi.core.student_id
// - learnerName: from cmi.core.student_name
// - successStatus, completionStatus, score, runtimeData, etc.
// Save the data keyed by both courseId and scoId
saveToDB(commitObject.courseId, commitObject.scoId, commitObject);
}
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/README.md
Commands to install required packages for the React Native project.
```bash
cd examples/react-native-offline
npm install
```
```bash
sudo chown -R $(whoami) ~/.npm
```
```bash
yarn install
```
--------------------------------
### Install Dependencies
Source: https://github.com/jcputney/scorm-again/blob/master/AGENTS.md
Installs project dependencies using npm. Requires Node.js version 20 or higher.
```bash
npm ci
```
--------------------------------
### SCORM 1.2 Time Format Examples
Source: https://github.com/jcputney/scorm-again/blob/master/docs/lms-integration/data-requirements-quick-reference.md
Examples of CMITimespan format strings used in SCORM 1.2.
```text
0000:00:00.00 - Zero time
0001:30:00.00 - 1 hour 30 minutes
0000:05:30.50 - 5 minutes 30.5 seconds
```
--------------------------------
### Course Data Flow and Integration
Source: https://github.com/jcputney/scorm-again/blob/master/examples/react-native-offline/PLAYER_IMPLEMENTATION.md
Illustrates the sequence of events from course download to player launch and SCORM API injection, highlighting offline support.
```text
Downloads Screen → [Download Complete] → Player Screen
Library Screen → [Launch Course] → Player Screen
Player Screen → [Back Button] → Previous Screen
```
```text
1. User downloads course (Downloads screen)
2. Course extracted to `${documentDirectory}/courses/${courseId}/`
3. User launches course (Library screen)
4. Player screen loads with courseId parameter
5. Player verifies course exists
6. Player injects SCORM API
7. Course runs with offline support
```
--------------------------------
### View Demo File Structure
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/player-wrapper-guide.md
Overview of the directory layout for the player-wrapper demo project.
```text
demos/player-wrapper/
├── shared/
│ ├── player-core.css # Shared CSS
│ ├── player-core.js # Shared utilities
│ └── mock-sco/ # Sample SCO content
├── scorm12-multi-sco/
│ ├── index.html # Player HTML
│ ├── player.js # SCORM 1.2 implementation
│ └── sample-course/ # Demo course
├── scorm2004-simple/
│ ├── index.html # Player HTML
│ ├── player.js # SCORM 2004 simple
│ └── sample-course/ # Demo course
└── scorm2004-sequenced/
├── index.html # Player HTML
├── player.js # SCORM 2004 sequenced
└── sample-course/ # Demo with hierarchy
```
--------------------------------
### SCORM 2004 Time Format Examples
Source: https://github.com/jcputney/scorm-again/blob/master/docs/lms-integration/data-requirements-quick-reference.md
Examples of ISO 8601 duration format strings used in SCORM 2004.
```text
PT0S - Zero time
PT1H30M - 1 hour 30 minutes
PT5M30.5S - 5 minutes 30.5 seconds
P1DT2H - 1 day 2 hours
```
--------------------------------
### Set and Get Suspend Data
Source: https://github.com/jcputney/scorm-again/blob/master/docs/api_usage/examples/scorm12_examples.md
Store and retrieve custom state information for the student using suspend data. Data should be stringified before setting and parsed after getting.
```javascript
// Set suspend data (for storing custom state information)
const suspendData = JSON.stringify({
lastPage: 5,
quizAttempts: 2,
userSelections: [1, 3, 4],
});
window.API.LMSSetValue("cmi.suspend_data", suspendData);
// Get suspend data
const retrievedSuspendData = window.API.LMSGetValue("cmi.suspend_data");
const parsedData = JSON.parse(retrievedSuspendData);
console.log("Last Page:", parsedData.lastPage);
```
--------------------------------
### JSDoc for HTTP Request Function
Source: https://github.com/jcputney/scorm-again/blob/master/typescript_guidelines.md
Use JSDoc comments for public APIs and complex functions, including parameter descriptions, return types, and examples. This example shows documentation for an HTTP request function.
```typescript
/**
* Processes an HTTP request to the LMS.
*
* @param url - The URL to send the request to
* @param params - The parameters to include in the request
* @param immediate - Whether to send the request immediately
* @returns A promise that resolves with the response
*/
function processHttpRequest(url: string, params: any, immediate: boolean): Promise {
// Implementation...
}
```
--------------------------------
### React Native Course Selection Component Example
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/mobile/react-native.md
Example React Native component for displaying a list of courses and navigating to the SCORM player. It loads available courses and uses navigation to pass the course ID.
```jsx
// Example Course Selection Component
const CourseLibraryScreen = ({ navigation }) => {
const [courses, setCourses] = useState([]);
useEffect(() => {
// Load available courses
loadAvailableCourses();
}, []);
const loadAvailableCourses = async () => {
// Read courses from directory or API
const availableCourses = [
{ id: 'course1', title: 'Introduction to SCORM', description: 'Learn the basics of SCORM' },
{ id: 'course2', title: 'Advanced Training', description: 'In-depth training module' },
];
setCourses(availableCourses);
};
return (
item.id}
renderItem={({ item }) => (
navigation.navigate('ScormPlayer', { courseId: item.id })}
>
{item.title}
{item.description}
)}
/>
);
};
```
--------------------------------
### Shared Module Koin Setup (Kotlin)
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/advanced/mobile/kotlin-multiplatform.md
Sets up dependency injection using Koin for the shared module. It defines singletons for repositories and factories for managers, including the ScormPlayerManager.
```kotlin
// shared/src/commonMain/kotlin/di/KoinModule.kt
val sharedModule = module {
single { ScormDataRepository(get())
factory { (courseId: String) ->
ScormPlayerManager(
webViewController = get(),
connectivityObserver = get(),
repository = get(),
courseId = courseId,
apiPath = get().getScormApiPath()
)
}
}
```
--------------------------------
### Initialize Multi-SCO Player Utilities
Source: https://github.com/jcputney/scorm-again/blob/master/docs-site/docs/lms-integration/multi-sco-support.md
Sets up the state tracker, sequencer, and rollup calculator within a class constructor. Requires importing the necessary helper classes from scorm-again/utilities/scorm12-lms-helpers.
```typescript
import Scorm12API from 'scorm-again';
import {
ScoStateTracker,
Scorm12Sequencer,
CourseRollupCalculator,
} from 'scorm-again/utilities/scorm12-lms-helpers';
class MultiScoPlayer {
private api: Scorm12API;
private tracker: ScoStateTracker;
private sequencer: Scorm12Sequencer;
private calculator: CourseRollupCalculator;
private currentScoId: string | null = null;
constructor(scoDefinitions: ScoDefinition[]) {
// Initialize state tracker
this.tracker = new ScoStateTracker();
// Initialize sequencer with your prerequisite system
this.sequencer = new Scorm12Sequencer(
scoDefinitions,
this.tracker,
(sco, tracker) => this.checkPrerequisites(sco.id)
);
// Initialize rollup calculator
this.calculator = new CourseRollupCalculator(this.tracker, {
scoreMethod: 'average',
completionMethod: 'all',
statusMethod: 'score_threshold',
passingScore: 80,
});
// Initialize SCORM API
this.api = new Scorm12API({
autocommit: true,
autocommitSeconds: 30,
// Enable global preferences for multi-SCO
globalStudentPreferences: true,
});
// Set up event handlers
this.setupEventHandlers();
}
// Your existing prerequisite system
private checkPrerequisites(scoId: string): boolean {
// Implement your LMS's prerequisite logic here
// Return true if the SCO can be launched
return true;
}
private setupEventHandlers(): void {
// Update state on every commit
this.api.on('LMSCommit', (data) => {
if (this.currentScoId) {
this.tracker.updateFromCmiData(this.currentScoId, data.cmi);
this.onStateChanged();
}
});
// Handle SCO completion
this.api.on('LMSFinish', (data) => {
if (this.currentScoId) {
// Final state update
this.tracker.updateFromCmiData(this.currentScoId, data.cmi);
// Get navigation suggestion
const suggestion = this.sequencer.processExitAction(
this.currentScoId,
data.cmi.core?.exit || ''
);
this.handleExitSuggestion(suggestion);
}
});
// Listen for state changes
this.tracker.onStateChange((event) => {
console.log(`SCO ${event.scoId} changed:`, event.changedFields);
this.persistState();
});
}
private onStateChanged(): void {
// Recalculate course rollup
const rollup = this.calculator.calculate();
// Update UI
this.updateProgressUI(rollup);
// Check for course completion
if (this.calculator.isCourseComplete()) {
this.onCourseComplete(rollup);
}
}
private handleExitSuggestion(suggestion: NavigationSuggestion): void {
console.log('Navigation suggestion:', suggestion);
switch (suggestion.action) {
case 'continue':
if (suggestion.targetScoId) {
this.showContinuePrompt(suggestion.targetScoId);
}
break;
case 'suspend':
this.showSuspendMessage();
break;
case 'retry':
this.showRetryPrompt(suggestion.targetScoId!);
break;
case 'exit':
this.showCourseMenu();
break;
}
}
}
```