### 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; } } } ```