{"id":22369432,"url":"https://github.com/superwall/superscript","last_synced_at":"2025-07-30T19:30:52.125Z","repository":{"id":252414723,"uuid":"838224461","full_name":"superwall/superscript","owner":"superwall","description":"Mobile Rust evaluator for the Common Expression Language ","archived":false,"fork":false,"pushed_at":"2025-07-23T15:07:34.000Z","size":9859,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-29T16:33:38.583Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/superwall.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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":"2024-08-05T07:51:41.000Z","updated_at":"2025-07-25T08:59:16.000Z","dependencies_parsed_at":"2024-11-12T16:22:34.667Z","dependency_job_id":"74da6ace-aa97-45ee-b12a-369f5341d5b0","html_url":"https://github.com/superwall/superscript","commit_stats":null,"previous_names":["superwall/cel-evaluator-rs","superwall/superscript"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/superwall/superscript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superwall%2Fsuperscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superwall%2Fsuperscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superwall%2Fsuperscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superwall%2Fsuperscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/superwall","download_url":"https://codeload.github.com/superwall/superscript/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superwall%2Fsuperscript/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267928946,"owners_count":24167430,"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-07-30T02:00:09.044Z","response_time":70,"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":[],"created_at":"2024-12-04T19:20:50.767Z","updated_at":"2025-07-30T19:30:52.097Z","avatar_url":"https://github.com/superwall.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Superscript Runtime\n\n[![Coverage Status](https://img.shields.io/badge/coverage-75.48%25-orange.svg)](./cobertura.xml)\n\nThis is the Superscript runtime library. Superscript is an expression language that builds upon CEL with enhanced null-safety, host integration, and mobile-optimized features.\n\nThe library can be used to evaluate Superscript expressions, with support for:\n- Dynamic property resolution from host platform\n- Built-in null-safety transformations  \n- Type normalization and coercion\n- WebAssembly (WASM) deployment\n\n## Installation\n\nTo build the library, you'll need to install:\n\n1. Rust (https://www.rust-lang.org/tools/install)\n2. Docker (for cross) (https://docs.docker.com/get-docker/)\n3. cross (https://github.com/cross-rs/cross)\n\n## Building\n\nTo build the library, run:\n\n```shell\n./build_android.sh\n```\n\n(note: for the first run you will need to `chmod +x build.sh` and wait a bit until the docker images are downloaded)\n\nThis will:\n\n- Clear the previously built jniLibs\n- Build the library using cross for Defined Android images (add a new image in the script if needed).\n- Copy the generated library to the `jniLibs` folder.\n- Use UniFFI to generate the JNI bindings and a `cel.kt` file at `./src/uniffi/cel/cel.kt`.\n- Copy the necessary files to the `./target/android/` folder.\n\n## Usage\n\nThe library defines three methods exposed to the host platform, which you can use depending on the type of\nexpression you want to evaluate:\n\n```idl\n // Evaluates a Superscript expression with provided variables and platform callbacks\n string evaluate_with_context(string definition, HostContext context);\n \n // Evaluates a Superscript AST expression with provided variables, platform callbacks\n string evaluate_ast_with_context(string definition, HostContext context);\n \n // Evaluates a pure Superscript AST expression\n string evaluate_ast(string ast);\n \n // Parses a Superscript expression into an AST\n string parse_to_ast(string expression);\n```\n\nThe `HostContext` object is a callback interface allowing us to invoke host (iOS/Android) functions from our Rust code.\nIt provides two functions:\n- `computed_property(name: String, args: String, callback: ResultCallback)` - For computed properties/functions\n- `device_property(name: String, args: String, callback: ResultCallback)` - For device properties/functions\n\nThe functions pass in the name and the args (if required, serialized as JSON) of the dynamic function/property to invoke, and use a callback to return the result asynchronously.\n\n\n\n### Android\n\nTo use the library in your Android application, you need to:\n- Copy the `jniLibs` folder from `./target/android` to Android project's `superwall/src/main` folder.\n- Copy the `cel.kt` file from `./src/uniffi/cel/cel.kt` to your Android project's `superwall/src/main/java/com/superwall/uniffi/cel/` folder.\n\n\nThe library exposes a single function currently:\n`fn evaluate_with_context(definition: String, ctx: HostContext) -\u003e String`\n\nThis function takes in a JSON containing the variables to be used and the expression to evaluate and returns the result.\nThe JSON is required to be in shape of `ExecutionContext`, which is defined as:\n\n```json\n{\n  \"variables\": {\n    // Map of variables that can be used in the expression\n    // The key is the variable name, and the value is the variable value wrapped together with a type discriminator\n    \"map\" : {\n      \"foo\": {\"type\": \"int\", \"value\": 100},\n      \"some_property\": {\"type\": \"string\", \"value\": \"true\"},\n      \"numbers\": {\n        \"type\" : \"list\",\n        \"value\" : [\n          {\"type\": \"int\", \"value\": 1},\n          {\"type\": \"int\", \"value\": 2},\n          {\"type\": \"int\", \"value\": 3}\n        ]\n      }\n    }\n  },\n  // Host-exposed functions for computed properties\n  \"computed\": {\n    \"daysSince\": [{\"type\": \"string\", \"value\": \"event_name\"}],\n    \"some_property\": []\n  },\n  // Host-exposed functions for device properties  \n  \"device\": {\n    \"daysSince\": [{\"type\": \"string\", \"value\": \"event_name\"}],\n    \"batteryLevel\": []\n  },\n  // The Superscript expression to evaluate\n  \"expression\": \"device.daysSince(\\\"app_launch\\\") \u003e 3.0 \u0026\u0026 computed.some_property == true\"\n}\n```\n\n## Key Features\n\n### Null-Safe Evaluation\nThe library automatically transforms expressions to be null-safe:\n- **Property access**: `obj.property` becomes `has(obj.property) ? obj.property : null`\n- **Function calls**: `device.function()` becomes `hasFn(\"device.function\") ? device.function() : false`\n\n### Built-in Functions\nSupported functions are defined in the `SUPPORTED_FUNCTIONS` constant:\n- `maybe` - Null coalescing operator\n- `toString`, `toBool`, `toInt`, `toFloat` - Type conversion extension functions\n- `has` - Checks if a property exists\n- `hasFn` - Checks if a function is available\n\n### Host Integration\nThe `HostContext` provides async callbacks to resolve dynamic properties:\n- `computed_property(name, args, callback)` - For computed functions\n- `device_property(name, args, callback)` - For device functions\n\nResults are returned as JSON-serialized `PassableValue` objects.\n\n### Variable Normalization\nThe library automatically normalizes string values to their appropriate types:\n- `\"true\"/\"false\"` → `Bool`\n- Numeric strings → `Int`/`UInt`/`Float`\n- Works recursively on nested objects and arrays\n\n## Documentation\n\nFor a detailed explanation of the expression evaluation process, see [interpretation-flow.md](interpretation-flow.md).\n\n### iOS\n\nTo use the library in your iOS application, you need to:\n\n1. Make the build script executable:\n- `chmod +x ./build_ios.sh`\n2. Run the build script:\n- `./build_ios.sh`\n3. Get the resulting XCframework from the `./target/xcframeworks/` folder and add it to your iOS project together \nwith generated swift files from `./target/ios`\n\n\nThis should give you a `HostContext` protocol:\n```swift\npublic protocol HostContextProtocol : AnyObject {\n    func computedProperty(name: String, args: String, callback: ResultCallback)\n    func deviceProperty(name: String, args: String, callback: ResultCallback)\n}\n```\n\nAnd a  `evaluateWithContext` method you can invoke:\n```swift\npublic func evaluateWithContext(definition: String, context: HostContext) -\u003e String\n```\n\n\n## Updating\n\nWhen updating the library, you need to pay attention to uniffi bindings and ensure they match the signature of the library functions.\nWhile it is tempting to migrate the library to use uniffi for the entire library, we still need to use JSON\nfor the input and output since UniFFI does not support recursive enums yet (such as PassableValue).\nFor that, track this [issue](https://github.com/mozilla/uniffi-rs/issues/396) for updates.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperwall%2Fsuperscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuperwall%2Fsuperscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperwall%2Fsuperscript/lists"}