{"id":19977309,"url":"https://github.com/phartenfeller/apex-off-grid","last_synced_at":"2025-09-08T05:45:50.533Z","repository":{"id":156104658,"uuid":"565450984","full_name":"phartenfeller/apex-off-grid","owner":"phartenfeller","description":"APEX Offline for everyone thanks to a Low Code API with Plug-Ins","archived":false,"fork":false,"pushed_at":"2024-08-24T11:25:32.000Z","size":7903,"stargazers_count":15,"open_issues_count":14,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-31T08:47:05.551Z","etag":null,"topics":["oracle-apex","orclapex","sqlite"],"latest_commit_sha":null,"homepage":"","language":"PLSQL","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/phartenfeller.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2022-11-13T13:07:02.000Z","updated_at":"2025-07-07T15:13:28.000Z","dependencies_parsed_at":"2024-11-13T03:39:26.340Z","dependency_job_id":null,"html_url":"https://github.com/phartenfeller/apex-off-grid","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/phartenfeller/apex-off-grid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phartenfeller%2Fapex-off-grid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phartenfeller%2Fapex-off-grid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phartenfeller%2Fapex-off-grid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phartenfeller%2Fapex-off-grid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phartenfeller","download_url":"https://codeload.github.com/phartenfeller/apex-off-grid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phartenfeller%2Fapex-off-grid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274140088,"owners_count":25229138,"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-09-08T02:00:09.813Z","response_time":121,"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":["oracle-apex","orclapex","sqlite"],"created_at":"2024-11-13T03:27:40.658Z","updated_at":"2025-09-08T05:45:50.479Z","avatar_url":"https://github.com/phartenfeller.png","language":"PLSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# APEX Off Grid\n\nAPEX Offline for everyone thanks to a Low Code API with Plug-Ins\n\n\u003cimg src=\"https://raw.githubusercontent.com/phartenfeller/apex-off-grid/main/assets/apex-off-grid-logo.png\" width=\"400\" \u003e\n\n[Watch this tutorial video](https://youtu.be/D9aTzsYK7MQ)\n\n## Features\n\n- Low Code API thanks to APEX Plug-Ins\n- Data Synchronization\n  - Input SQL Query -\u003e Data gets downloaded and synced back\n  - Changes get saved to local storage\n  - Changes get synced back to server\n  - Conflict detection and resolution possible with your own logic\n- Super fast and able to handle lots of data amounts thanks to SQLite\n## How to get started\n\n### Prerequisites\n\n- APEX \u003e= 23.2\n- Following HTTP Response Headers are required\n\n```\nCross-Origin-Embedder-Policy: require-corp\nCross-Origin-Opener-Policy: same-origin\n```\n\u003cdetails\u003e\n  \u003csummary\u003eCurrent APEX Bug: setting headers in shared components does not work!\u003c/summary\u003e\n\nThere is a setting in APEX to set these headers. [There currently is a bug](https://twitter.com/chrisneumueller/status/1649367365342093313?s=20) that results in these headers not being set on Plug-In files. So this solution **currently does not work**.\n\n![App \u003e Shared Components \u003e Security \u003e Browser Security \u003e HTTP Response Headers](./assets/http-headers-apex.png)\n\n\u003c/details\u003e\n\n**So you need to set these headers in your Webserver or Proxy.**\n\n- [Here is an example](https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/23.4/ordig/miscellaneous-configuration-options-of-ORDS.html#GUID-A3798C5A-C6C6-40A2-826F-CE1CF0B8DDE2)  on how to it with ORDS standalone (Example 5-3).\n\n[More info on the header requirement](https://sqlite.org/wasm/doc/trunk/persistence.md#:~:text=COOP%20and%20COEP%20HTTP%20Headers).\n\n### Installation\n\nGo to the latest release and download the installation zip file. For the base installation you run the tables and package scripts. Afterwards import the plug-ins.\n\n### Install sample app\n\nRead the [Installation Guide](./sample-apps/recipes/readme.md)\n\n### How to build your own app\n\n1. Import Plug-Ins from release download into your app\n2. [Watch this tutorial video](https://youtu.be/D9aTzsYK7MQ)\n\nx. After you defined your storage, you have to define the DML logic in the package `offline_data_sync_api.sync_row`:\n\n```sql\ncase \n  when pi_sync_storage_id = 'ingredients' and pi_sync_storage_version = 1 then\n\n\t  recipe_offline_sync_api.sync_ingredients_v1 (\n\t\t\tpi_json                 =\u003e l_json\n\t\t, pi_change_type          =\u003e l_change_type\n\t\t, pi_change_date          =\u003e l_change_date\n\t\t, pi_updated_by           =\u003e v('APP_USER')\n\t\t, po_success              =\u003e po_success\n\t\t, po_sync_fail_reason     =\u003e po_sync_fail_reason\n\t\t, po_sync_device_pk       =\u003e po_sync_device_pk\n\t\t, po_snyc_db_pk           =\u003e po_snyc_db_pk\n\t  );\n```\n\n## Caution\n\n- This is a proof of concept\n- There is no warranty or support garantee\n- I am working on this in my free time \n- I am not responsible for any data loss or damage\n- Only a small fraction of APEX features are supported\n- You can't just make your existing APEX app offline capable with this. You have to build your app with this in mind.\n- The users could download the Database and get control over all offline available data\n- The users could manipulate the data in the local database with malicious intent\n\n## Resources\n\nDownload SQLite WASM buidl from [here](https://sqlite.org//download.html#:~:text=WebAssembly%20%26%20JavaScript)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphartenfeller%2Fapex-off-grid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphartenfeller%2Fapex-off-grid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphartenfeller%2Fapex-off-grid/lists"}