{"id":15289098,"url":"https://github.com/integralla/xapi-scala","last_synced_at":"2025-10-08T19:26:47.254Z","repository":{"id":253273521,"uuid":"841063999","full_name":"integralla/xapi-scala","owner":"integralla","description":"Scala library for working with Experience API (xAPI) resources","archived":false,"fork":false,"pushed_at":"2024-08-30T21:42:01.000Z","size":471,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T05:44:49.460Z","etag":null,"topics":["edtech","educational-technology","scala","xapi"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/integralla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-11T14:34:22.000Z","updated_at":"2024-08-30T21:42:04.000Z","dependencies_parsed_at":"2024-08-28T18:30:44.840Z","dependency_job_id":"47ecd3bc-9c04-4e2f-a0fb-86f44751f1d7","html_url":"https://github.com/integralla/xapi-scala","commit_stats":null,"previous_names":["integralla/xapi-scala"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/integralla/xapi-scala","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integralla%2Fxapi-scala","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integralla%2Fxapi-scala/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integralla%2Fxapi-scala/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integralla%2Fxapi-scala/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/integralla","download_url":"https://codeload.github.com/integralla/xapi-scala/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integralla%2Fxapi-scala/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000704,"owners_count":26082805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["edtech","educational-technology","scala","xapi"],"created_at":"2024-09-30T15:59:16.598Z","updated_at":"2025-10-08T19:26:47.227Z","avatar_url":"https://github.com/integralla.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xAPI Scala\n\n[![Build Status](https://github.com/integralla/xapi-scala/actions/workflows/scala.yml/badge.svg)](https://github.com/integralla/xapi-scala/actions/workflows/scala.yml)\n\n## Description\n\nScala library for creating and working with Experience API (xAPI) resources (such as statements\nand documents).\n\n\u003e The [Experience API (xAPI)](https://xapi.ieee-saopen.org/) is a standard that describes an\n\u003e interoperable means to document and communicate information about learning experiences. It\n\u003e specifies a structure to describe learning experiences and defines how these descriptions can be\n\u003e exchanged electronically.\n\nThe library has been cross-built for Scala 3 and Scala 2.13, and is available\nfrom [Maven Central](https://central.sonatype.com/search?namespace=io.integralla\u0026q=xapi-scala).\n\n```sbt\n/* sbt */\nlibraryDependencies += \"io.integralla\" %% \"xapi-scala\" % \"1.0.0\"\n```\n\n```scala worksheet\n/* Scala CLI */\n//\u003e using dep io.integralla:xapi-scala_3:1.0.0\n```\n\n```shell\n# Apache Spark\nspark-shell --packages io.integralla:xapi-scala_2.13:1.0.0\n```\n\n## Basic Usage\n\n### Statement Creation\n\nCreate a basic statement with an explicit identifier:\n\n```scala\nimport io.integralla.xapi.model._\n\nval statement = Statement(\n  actor = Agent(\n    objectType = Some(StatementObjectType.Agent),\n    mbox = Some(MBox(\"mailto:demo@example.com\"))\n  ),\n  verb = StatementVerb(\n    id = IRI(\"http://adlnet.gov/expapi/verbs/created\"),\n    display = Some(LanguageMap(Map(\"en-US\" -\u003e \"created\")))\n  ),\n  `object` = StatementObject(\n    Activity(None, IRI(\"http://example.adlnet.gov/xapi/example/activity\"), None)\n  )\n)\n```\n\n### Encoding / Decoding\n\nEncode the statement as JSON, using the `toJson` method:\n\n```scala\nval encoded: String = statement.toJson(spaces = true)\n```\n\n```json\n\n{\n  \"actor\": {\n    \"objectType\": \"Agent\",\n    \"mbox\": \"mailto:demo@example.com\"\n  },\n  \"verb\": {\n    \"id\": \"http://adlnet.gov/expapi/verbs/created\",\n    \"display\": {\n      \"en-US\": \"created\"\n    }\n  },\n  \"object\": {\n    \"id\": \"http://example.adlnet.gov/xapi/example/activity\"\n  }\n}\n```\n\nDecode a JSON representation of a statement, using an `apply` method:\n\n```scala\nval decoded: Try[Statement] = Statement(encoded)\nassert(decoded.isSuccess)\nassert(decoded.get == statement)\n```\n\n## Notable Features\n\n### Encoding / Decoding\n\nA `Statement`, and every other data type supported by the model, can be encoded as a JSON string\nusing\na built-in method called `toJson` as demonstrated above in the \"Basic Usage\" section.\n\nSimilarly, every supported data type supports decoding from JSON using an `apply` method that is\nmade available via a companion object to the data type case class or enum.\n\nThis library uses [circe](https://circe.github.io/circe/), for encoding / decoding. Semi-automatic\nderivation is used in most cases, with custom codecs used for complex scenarios.\n\n### Statement Validation\n\nUpon object creation (including decoding), a number of validations are performed to ensure that the\nstatement is structurally correct, and that properties that can / should be parsed and handled as a\nspecific reference type (for example, an IRI) can be parsed and handled as such.\n\nIf validation fails, a `StatementValidationException` will be thrown with an explanatory message\nindicating why validation failed.\n\nJSON schema validation is assumed for basic validation needs, including pattern matching against\nstrings for such things as UUIDs, hashes, etc.\n\n### Logical Equivalence Testing\n\nThe xAPI specification requires the ability to test statements for logical equivalence in certain\ncontexts such as ensuring statement immutability and verifying statement signatures. This can be\naccomplished using an `isEquivalentTo` method available for the `Statement` data type (and most\nothers).\n\n```scala\nval left: Statement = ???\nval right: Statement = ???\nassert(left.isEquivalentTo(right))\n```\n\n### Listing Agent / Activity References\n\nFiltering statements based upon whether they reference an agent and/or activity can become complex\ndue to the fact that either object type can be referenced in multiple places. This gets even more\ndifficult when dealing with sub-statements. In order to make all of this easier, the `Statement`\ndata type supports methods to retrieve a list of agent references, or a list of activity references,\nwhere the reference data type provides context to facilitate filtering requirements.\n\n| Method Name          | Return Type               | Description                                                              |\n|----------------------|---------------------------|--------------------------------------------------------------------------|\n| `activityReferences` | `List[ActivityReference]` | Extracts and returns all activities (if any) referenced by the statement |\n| `agentReferences`    | `List[AgentReference]`    | A list of agent references across all parts of the statement             |\n\nFor an activity, the reference model defines the type of reference (for example, as a statement\nobject or\na parent, grouping, category, or other context activity), as well as a property to indicate whether\nthe reference occurs in a sub-statement.\n\nFor an agent, the reference model defines the type of reference (for example, an actor, object,\nauthority,\ninstructor, team), whether the reference occurs in a sub-statement, and whether it is as a\nstandalone agent or as member of a group.\n\n### Agent / Group Identifiers Helpers\n\nThe xAPI specification defines four types of Inverse Functional Identifiers (IFI) to uniquely\nidentify agents or identified groups within a statement. The library offers a couple of methods to\nsimplify working with these identifiers:\n\n| Method Name | Return Type      | Description                                                                                      |\n|-------------|------------------|--------------------------------------------------------------------------------------------------|\n| `ifiType`   | `Option[String]` | The IFI type name (for example, `account`)                                                       |\n| `ifiValue`  | `Option[String]` | The IFI value as a string (for example, `http://www.example.com#123456`)                         |\n| `ifiKey`    | `Option[String]` | An IFI key composed of its type and value (for example, `account#http://www.example.com#123456`) |\n\nThe `ifiKey` method is particularly useful for filtering or grouping by agent.\n\n### Statement Manipulation\n\nOn decoding statements, we've chosen to keep the modifications to the minimum required for\nvalidation, deferring all other necessary manipulations to downstream processing such as would\ntypically occur before persistence (for example, adding an identifier or setting the `stored`\ntimestamp property).\n\nThe only mutation made on decoding is to change the `context.contextActivities` property to an array\nif it is set to a single `Activity` object (something allowed for backwards compatibility only).\n\n### Other\n\nPlease consult the source code, which is well documented, for additional features / details.\n\n## Contributing\n\nAll suggestions are welcome!\n\nThis project uses the `sbt` build tool:\n\n```shell\nsbt 'compile;test'\n```\n\nUse `scalafmt` to ensure code style compliance:\n\n```shell\nsbt scalafmt\n```\n\n## Sponsor\n\nWe offer commercial development services, specializing in educational technology and data analytics.\nContact us to learn more ([integralla.com](https://integralla.com/)).\n\n## License\n\nCopyright 2024 Integralla LLC (https://integralla.com/)\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintegralla%2Fxapi-scala","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fintegralla%2Fxapi-scala","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintegralla%2Fxapi-scala/lists"}