{"id":48295510,"url":"https://github.com/hypermedia-app/sparqlc","last_synced_at":"2026-04-04T23:32:04.175Z","repository":{"id":340397210,"uuid":"1162624839","full_name":"hypermedia-app/sparqlc","owner":"hypermedia-app","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-24T20:18:41.000Z","size":278,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-24T20:54:40.336Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/hypermedia-app.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-20T13:52:15.000Z","updated_at":"2026-02-24T20:17:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hypermedia-app/sparqlc","commit_stats":null,"previous_names":["hypermedia-app/sparqlc"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/hypermedia-app/sparqlc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermedia-app%2Fsparqlc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermedia-app%2Fsparqlc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermedia-app%2Fsparqlc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermedia-app%2Fsparqlc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hypermedia-app","download_url":"https://codeload.github.com/hypermedia-app/sparqlc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hypermedia-app%2Fsparqlc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31419216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":"2026-04-04T23:32:03.592Z","updated_at":"2026-04-04T23:32:04.162Z","avatar_url":"https://github.com/hypermedia-app.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sparqlc monorepo\n\nA set of tools for compiling and using SPARQL queries as first‑class modules across Node.js, Vite, esbuild, and TypeScript.\n\nPackages (in usage order):\n- `sparqlc` – core compiler and runtime (JS API + CLI)\n- `node-loader-sparql` – Node.js loader to import `.rq` files directly\n- `vite-plugin-sparql` – Vite plugin to import `.rq` in web apps\n- `esbuild-plugin-sparql` – esbuild plugin to import `.rq`\n- `ts-plugin-sparqlc` – TypeScript language service plugin to get strong types for `.rq` imports\n\n## Installation\n\nIn most projects you do not install `sparqlc` directly. Instead, add the high‑level integration you use — it will pull `sparqlc` as a dependency:\n\n- Node.js (import `.rq` in Node):\n  ```sh\n  npm i -D node-loader-sparql\n  ```\n- Vite (web apps):\n  ```sh\n  npm i -D vite-plugin-sparql\n  ```\n- esbuild:\n  ```sh\n  npm i -D esbuild-plugin-sparql\n  ```\n- TypeScript editor types for `.rq` imports:\n  ```sh\n  npm i -D ts-plugin-sparqlc\n  ```\n\nOnly install `sparqlc` itself if you want to call the core API or use the CLI directly:\n\n```sh\nnpm i sparqlc\n```\n\nBelow you’ll find usage for each package.\n\n---\n\n## 1) `sparqlc` (core)\n\n`sparqlc` compiles a SPARQL string into a small executable function with:\n- `code` – the emitted function source (stringified)\n- `returnType` – inferred SPARQL result kind: `Select | Construct | Ask | Update | unknown`\n- `execute` – a function that, when given parameters and an executor `{ env, client, processors }`, will either:\n  - return a SPARQL string (when no `client` is provided), or\n  - execute the query using `sparql-http-client` and return typed results based on `returnType`\n\n### API usage\n\n```ts\nimport { compile } from 'sparqlc'\nimport env from '@zazuko/env'\nimport { StreamClient } from 'sparql-http-client'\n\nconst source = `\nPREFIX foaf: \u003chttp://xmlns.com/foaf/0.1/\u003e\nSELECT ?name WHERE { ?s foaf:name ?name }\nLIMIT 10\n`\n\nconst { execute, returnType } = compile(source)\nconsole.log(returnType) // e.g. 'Select'\n\n// Build executor options\nconst client = new StreamClient({ endpointUrl: 'https://dbpedia.org/sparql' })\n\n// Optional parameterization examples (URLSearchParams, object, or Map\u003cTerm, Term|Term[]\u003e)\nconst params = { name: env.literal('Alice') }\n\n// Execute:\nconst rows = await execute(params, { env, client })\n// If you omit `client`, execute(...) returns the final SPARQL string instead\n```\n\n### Reference parameters with `sparqlc:param`\n\nYou can declare and consume query parameters inside `.rq` files using the RDF property/function identified by `https://sparqlc.described.at/param` (IRI). Use a prefix for convenience:\n\n```sparql\nPREFIX sparqlc: \u003chttps://sparqlc.described.at/\u003e\n```\n\n- (Recommended) Function style: `sparqlc:param(\"name\")`\n  - Can be easily inlined in `BIND`, `FILTER`, or anywhere an expression is allowed.\n  - Example:\n    ```sparql\n    PREFIX foaf: \u003chttp://xmlns.com/foaf/0.1/\u003e\n    PREFIX sparqlc: \u003chttps://sparqlc.described.at/\u003e\n    \n    SELECT ?name ?age WHERE {\n      ?s foaf:name ?name ; foaf:age ?age .\n      FILTER (?age \u003e= sparqlc:param(\"minAge\"))\n    }\n    ```\n\n- Pattern style: `?variable sparqlc:param \"name\" .`\n  - This binds the value of the parameter `\"name\"` to the SPARQL variable `?variable`.\n  - Example:\n    ```sparql\n    PREFIX foaf: \u003chttp://xmlns.com/foaf/0.1/\u003e\n    PREFIX sparqlc: \u003chttps://sparqlc.described.at/\u003e\n    \n    SELECT ?person WHERE {\n      ?name sparqlc:param \"person\" .  \n    \n      ?person a foaf:Person ;\n              foaf:name ?name .\n    }\n    ```\n    Runtime call:\n    ```ts\n    import env from '@zazuko/env'\n    const rows = await execute({ person: env.namedNode('http://example.com/alice') }, { env, client })\n    ```\n\nPassing parameters at runtime\n- You may pass parameters as:\n  - `Record\u003cstring, Term\u003e`: `{ person: env.namedNode('...'), minAge: env.literal('18', xsdInteger) }`\n  - `URLSearchParams`: `new URLSearchParams([[\"person\", \"http://example.com/alice\"], [\"minAge\", \"18\"]])` (simple string values)\n  - `Map\u003cTerm, Term | Term[]\u003e` for full control\n- Values are RDFJS `Term`s. For typed literals, construct them via your RDF environment (e.g., `@zazuko/env`).\n\nNotes\n- The parameter IRI is exactly `https://sparqlc.described.at/param`.\n- Use `PREFIX sparqlc: \u003chttps://sparqlc.described.at/\u003e` so `sparqlc:param` expands to that IRI in both triple and function forms.\n- Arrays (`Term[]`) are supported by the runtime API for positions that accept multiple terms (e.g., via custom processors). Your usage may vary depending on processors you apply.\n\n### CLI usage\n\n`sparqlc` also ships a tiny CLI wrapper that can be used to process a query and print the effective query:\n\n```sh\nnpx sparqlc file.rq [param1=value1 param2=value2 ...]\n```\n\nParameter values are string parsed using [rdf-string](https://npm.im/rdf-string).\n\nTypical pattern is to use the library API in your build tool via the plugins below; the CLI is primarily for local debugging.\n\n---\n\n## 2) `node-loader-sparql`\n\nImport `.rq` files directly in Node.js. The loader compiles the query on‑the‑fly and makes the default export be the executable query function (typed at runtime) compatible with `sparqlc`’s `execute` signature.\n\n### Run with Node’s loader flag\n\n```sh\nnode --experimental-loader=node-loader-sparql ./app.mjs\n# Node 22+ keeps the loader flag; ES module specifiers are supported\n```\n\nNow you can do:\n\n```ts\n// app.mjs (or .ts with tsx/ts-node)\nimport query from './queries/find-people.rq'\nimport rdf from '@zazuko/env'\nimport { StreamClient } from 'sparql-http-client'\n\nconst env = rdf\nconst client = new StreamClient({ endpointUrl: 'https://dbpedia.org/sparql' })\n\nconst rows = await query({ env, client })\nconsole.log(rows)\n```\n\n---\n\n## 3) `vite-plugin-sparql`\n\nUse `.rq` files seamlessly in Vite projects. The plugin compiles the query at transform time.\n\n### Setup\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport sparql from 'vite-plugin-sparql'\n\nexport default defineConfig({\n  plugins: [sparql],\n})\n```\n\n### Usage in app code\n\n```ts\nimport query from './queries/people.rq'\nimport rdf from '@zazuko/env'\nimport { StreamClient } from 'sparql-http-client'\n\nconst env = rdf\nconst client = new StreamClient({ endpointUrl: '/sparql' })\n\nconst data = await query({ env, client })\n```\n\n---\n\n## 4) `esbuild-plugin-sparql`\n\nAdd support for importing `.rq` in esbuild builds.\n\n### Minimal build script\n\n```ts\n// build.ts\nimport { build } from 'esbuild'\nimport sparql from 'esbuild-plugin-sparql'\n\nawait build({\n  entryPoints: ['src/index.ts'],\n  bundle: true,\n  format: 'esm',\n  platform: 'node',\n  plugins: [sparql],\n})\n```\n\nThen in your sources:\n\n```ts\nimport query from './queries/people.rq'\n// … use query.execute({ env, client })\n```\n\nIf you’re bundling for Node ESM and also using `require()` somewhere, you may need to add a `banner` to create a `require` shim (see the repo tests for an example).\n\n---\n\n## 5) `ts-plugin-sparqlc`\n\nTypeScript language service plugin that gives proper types for `.rq` default exports based on the query’s `returnType`. That means you’ll get:\n- Autocomplete/typed signatures for `execute`\n- Distinct return types for `Select`, `Construct`, `Ask`, and `Update`\n\n### Configure `tsconfig.json`\n\n```jsonc\n{\n  \"compilerOptions\": {\n    // Let TS consider non‑TS imports so the plugin can attach types\n    \"allowArbitraryExtensions\": true,\n\n    // Enable the plugin\n    \"plugins\": [\n      { \"name\": \"ts-plugin-sparqlc\" }\n    ]\n  }\n}\n```\n\n### What you get in TS\n\n```ts\nimport query from './queries/people.rq'\n\n// Hovering shows: ExecuteSelect | ExecuteConstruct | ... depending on the query\nconst result = await query({ env, client })\n```\n\nThe plugin internally generates virtual `.d.rq.ts` type stubs next to your `.rq` files and keeps them in sync with your editor session—no files are written to disk.\n\n---\n\n## Runtime expectations\n\nAll environments ultimately call `query.execute(..., { env, client, processors? })` produced by `sparqlc`.\n- `env`: an RDF/JS environment (e.g. `@zazuko/env`)\n- `client`: optional `sparql-http-client` client; when omitted, `execute` returns the final SPARQL string instead of performing a request\n- `processors`: optional array of `@hydrofoil/sparql-processor` instances to transform the parsed query before serialization\n\n## Examples\n\nA typical `.rq` file:\n\n```sparql\n# queries/people.rq\nPREFIX foaf: \u003chttp://xmlns.com/foaf/0.1/\u003e\nSELECT ?name WHERE { ?s foaf:name ?name }\nLIMIT 5\n```\n\nAnd consuming it (works with the loader/plugins):\n\n```ts\nimport query from './queries/people.rq'\nimport rdf from '@zazuko/env'\nimport { StreamClient } from 'sparql-http-client'\n\nconst env = rdf\nconst client = new StreamClient({ endpointUrl: 'https://dbpedia.org/sparql' })\n\nconst rows = await query.execute({ env, client })\n```\n\n---\n\n## License\n\nMIT © Tomasz Pluskiewicz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypermedia-app%2Fsparqlc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhypermedia-app%2Fsparqlc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhypermedia-app%2Fsparqlc/lists"}