{"id":18698429,"url":"https://github.com/plurid/elementql","last_synced_at":"2025-11-08T17:30:34.485Z","repository":{"id":57137324,"uuid":"206914890","full_name":"plurid/elementql","owner":"plurid","description":"Query Web Elements at Runtime","archived":false,"fork":false,"pushed_at":"2023-04-26T13:48:37.000Z","size":4914,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-28T05:46:21.810Z","etag":null,"topics":["element","query-language","web"],"latest_commit_sha":null,"homepage":"https://elements.plurid.cloud","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/plurid.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}},"created_at":"2019-09-07T04:21:31.000Z","updated_at":"2022-08-15T08:23:07.000Z","dependencies_parsed_at":"2024-11-07T11:34:28.702Z","dependency_job_id":"ffa1b97c-8dfc-436f-99ae-6c6e2b7bda54","html_url":"https://github.com/plurid/elementql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Felementql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Felementql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Felementql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plurid%2Felementql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plurid","download_url":"https://codeload.github.com/plurid/elementql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239558934,"owners_count":19658934,"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","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":["element","query-language","web"],"created_at":"2024-11-07T11:28:18.405Z","updated_at":"2025-11-08T17:30:34.442Z","avatar_url":"https://github.com/plurid.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca target=\"_blank\" href=\"https://elements.plurid.cloud\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/plurid/elementql/master/about/identity/elementql-logo.png\" height=\"250px\"\u003e\n    \u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/plurid/elementql/blob/master/LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-DEL-blue.svg?colorB=1380C3\u0026style=for-the-badge\" alt=\"License: DEL\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\n\n\u003ch1 align=\"center\"\u003e\n    ElementQL\n\u003c/h1\u003e\n\n\n\u003ch3 align=\"center\"\u003e\n    Query Web Elements\n\u003c/h3\u003e\n\n\n\n\u003cbr /\u003e\n\n\n`ElementQL` is a query language specification and implementation to query a server for Web Elements source code in order to render them on the client.\n\n\n### Contents\n\n+ [Description](#description)\n    + [Current State](#current-state)\n    + [ElementQL Proposal](#elementql-proposal)\n+ [Usage](#usage)\n    + [Server](#server)\n        + [NodeJS](#nodejs)\n        + [Go](#go)\n        + [Python](#python)\n    + [Client](#client)\n        + [React](#react)\n+ [Plugins](#plugins)\n    + [Babel](#babel)\n    + [TypeScript](#typescript)\n    + [Minify](#minify)\n+ [Packages](#packages)\n+ [Codeophon](#codeophon)\n\n\n\n## Description\n\n### Current State\n\nConsider the following Web Element which uses [React](https://reactjs.org/)\n\n``` typescript\nconst HelloElementQL = () =\u003e {\n    return React.createElement('div', null, 'Hello from ElementQL');\n}\n```\n\nWhen embedded into a standard `React` rendering process, the `HelloElementQL` functional element will generate a `div` containing the text `Hello from ElementQL`.\n\nThe normal manner of sending the element to the browser is by packing it up into an `Application`, in a large `JavaScript` `index.js` file, which gets attached to a `index.html` with a `script` tag and then gets sent by the server to the client.\n\n\n### ElementQL Proposal\n\nThe manner proposed by `ElementQL` is to let the client request only the required elements at runtime from a server and receive only the particular element-specific module.\n\n\n\n## Usage\n\n### Server\n\n#### NodeJS\n\n##### Install\n\nThe [`NodeJS`](https://nodejs.org) server can be installed running the command\n\n``` bash\nnpm install @plurid/elementql-server\n```\n\nor\n\n``` bash\nyarn add @plurid/elementql-server\n```\n\n##### Start\n\nThe simplest `ElementQL` server requires only to be started, the elements will be served from the default `./elements` path\n\n``` typescript\n// server.js\nimport ElementQLServer from '@plurid/elementql-server';\n\n\nconst server = new ElementQLServer();\n\nserver.start();\n```\n\nThe server will then accept requests on the `http://localhost:21100/elementql` URL for the elements in the `./elements` directory.\n\n##### Elements\n\nThe `./elements` directory has a structure of folders with element-specific files: `.js`, `.jsx`, `.ts`, `.tsx`, or `.css`. For example\n\n```\n.\n|- server.js\n|- elements\n|   |- HelloElementQL\n|   |   |- index.js\n|   |-\n|-\n```\n\n##### Options\n\nThe `ElementQLServer` Object can receive an options object\n\n``` typescript\nimport {\n    ElementQLServerOptions,\n} from '@plurid/elementql-server';\n\n\n/** defaults */\nconst options: ElementQLServerOptions = {\n    protocol: 'https',                          /** default for production; for development: `'http'` */\n    domain: '',                                 /** the domain for the server, e.g. example.com */\n                                                /** will be used to resolve elements relative and library imports */\n    port: 21100,\n\n    rootDirectory: process.cwd(),\n    buildDirectory: 'build',                    /** relative to the root directory */\n    nodeModulesDirectory: 'node_modules',       /** relative to the root directory */\n    elementqlDirectory: '.elementql',           /** relative to the build directory */\n    transpilesDirectory: 'transpiles',          /** relative to the elementql directory */\n\n    elementsDirectories: [                      /**/\n        'elements',                             /** relative to the build directory */\n    ],                                          /**/\n    libraries: {},\n    endpoint: '/elementql',\n    allowOrigin: ['*'],\n    allowHeaders: ['*'],\n    plugins: [                                  /**/\n        'minify',                               /** default for production; for development: `[]` */\n    ],                                          /**/\n\n    verbose: true,\n    open: true,\n    playground: false,\n    playgroundEndpoint: '/playground',\n\n    store: null,\n    metadataFilename: 'metadata.json',\n};\n```\n\n##### Requests\n\nIn production, an [ElementQL Client](#client) is recommended. In development/testing, the requests for elements can be made using the `POST` method with a `Content-Type` header of `application/json` or `application/elementql`. For example\n\nJSON\n\n``` bash\ncurl http://localhost:21100/elementql \\\n    -H \"Content-Type: application/json\" \\\n    -v --data '{\"elements\":[{\"name\":\"HelloElementQL\"}]}'\n```\n\nElementQL\n\n``` bash\ncurl http://localhost:21100/elementql \\\n    -H \"Content-Type: application/elementql\" \\\n    -v --data 'elements{HelloElementQL}'\n```\n\n##### Metadata\n\nIn each element directory there can be an `elementql.yaml` file with metadata specific to the element\n\n``` yaml\n# the element name derived from the directory name will be overwrriten with `OverwriteName`\nname: OverwriteName\n```\n\n\n\n#### Go\n\nThe `elementql-server` for `Go` is a `go 1.14` module.\n\n\n#### Python\n\n\n\n\n### Client\n\n#### React\n\nConsidering the standard `React` application, using `ElementQL` involves\n\n+ creating an `elementql.yaml` configuration file,\n\n``` yaml\n---\nglobals:\n  react: React\n  react-dom: ReactDOM\norigins:\n  elementql: http://localhost:21100/elementql\n  application: http://localhost:8005\nbootloader: './source/index.js'\nentry: './app/index.js'\n```\n\n\n+ creating the `service-worker`,\n\n``` js\nconst elementQLServiceWorker = './node_modules/@plurid/elementql/distribution/service-worker.js';\n\n\nimportScripts(elementQLServiceWorker);\n```\n\n\n+ creating and running the `metabootloader`,\n\n``` js\nconst metabootloader = require('@plurid/elementql/distribution/metabootloader').default;\n\n\nmetabootloader();\n```\n\n\n+ creating and running `useLibraries`\n\n``` js\nconst {\n    libraries,\n    useLibraries,\n} = require('@plurid/elementql');\n\n\n\nconst usedLibraries = {\n    react: libraries.react,\n    reactDom: libraries.reactDom,\n};\n\nconst buildDirectory = 'build';\n\n\nuseLibraries({\n    libraries: usedLibraries,\n    buildDirectory,\n});\n```\n\n\n+ defining an `ElementQL`/`JSON` request,\n+ instantiating an `ElementQLClient` with the `URL` for the `ElementQL` server endpoint,\n+ and making the request with the `useEffect`, `useState` standard `React` hooks,\n+ or with the `useElementQL` custom hook.\n\n\n``` tsx\nimport React, {\n    useEffect,\n    useState,\n} from 'react';\n\nimport ElementQLClientReact, {\n    useElementQL,\n} from '@plurid/elementql-client-react';\n\n\n\nconst elementQLClient = new ElementQLClientReact({\n    url: 'http://localhost:21100/elementql',\n});\n\nconst ElementQLJSONRequest = {\n    elements: [\n        {\n            name: 'HelloElementQL',\n        },\n    ],\n};\n\n\nconst AppWithHook: React.FC\u003cany\u003e = () =\u003e {\n     const Elements = useElementQL(\n        elementQLClient,\n        ElementQLJSONRequest,\n        'json',\n    );\n\n    return (\n        \u003c\u003e\n            {Elements \u0026\u0026 (\n                \u003cElements.HelloElementQL /\u003e\n            )}\n        \u003c/\u003e\n    );\n}\n\n\nconst App: React.FC\u003cany\u003e = () =\u003e {\n    const [Elements, setElements] = useState\u003cany\u003e();\n\n    useEffect(() =\u003e {\n        let mounted = true;\n\n        const fetchElements = async () =\u003e {\n            const {\n                status,\n                Elements,\n            }: any = await elementQLClient.get(\n                ElementQLJSONRequest,\n                'json',\n            );\n\n            if (!status || !mounted) {\n                return;\n            }\n\n            setElements(Elements);\n        }\n\n        fetchElements();\n\n        return () =\u003e {\n            mounted = false;\n        }\n    }, []);\n\n    return (\n        \u003c\u003e\n            {Elements \u0026\u0026 (\n                \u003cElements.HelloElementQL /\u003e\n            )}\n        \u003c/\u003e\n    );\n}\n\n\nexport default App;\n```\n\n\n\n## Plugins\n\n\n### Babel\n\nUses [Babel](https://github.com/babel/babel) to transpile `.js` and `.jsx` element files.\n\n\n### TypeScript\n\nUses [TypeScript](https://github.com/microsoft/TypeScript) to transpile `.ts` and `.tsx` element files.\n\n\n### Minify\n\nUses [Terser](https://github.com/terser/terser) to minify the element files.\n\n\n\n## Packages\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/elementql\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/elementql.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql][elementql] • base\n\n[elementql]: https://github.com/plurid/elementql/tree/master/packages/elementql\n\n\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/elementql-client\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/elementql-client.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql-client][elementql-client]\n\n[elementql-client]: https://github.com/plurid/elementql/tree/master/packages/elementql-client\n\n\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/elementql-client-react\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/elementql-client-react.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql-client-react][elementql-client-react] • `react` client\n\n[elementql-client-react]: https://github.com/plurid/elementql/tree/master/packages/elementql-client-react\n\n\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/elementql-express\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/elementql-express.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql-express][elementql-express] • `express` middleware\n\n[elementql-express]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-express\n\n\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/elementql-parser\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/elementql-parser.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql-parser][elementql-parser]\n\n[elementql-parser]: https://github.com/plurid/elementql/tree/master/packages/elementql-parser\n\n\n\n\u003ca target=\"_blank\" href=\"https://www.npmjs.com/package/@plurid/elementql-server\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@plurid/elementql-server.svg?logo=npm\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql-server][elementql-server-node] • NodeJS server\n\n[elementql-server-node]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-node\n\n\n\n\u003ca target=\"_blank\" href=\"\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/go-v0.0.0-blue?\u0026colorB=1380C3\u0026style=for-the-badge\" alt=\"Version\"\u003e\n\u003c/a\u003e\n\n[@plurid/elementql-server][elementql-server-go] • Go server\n\n[elementql-server-go]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-go\n\n\n\n[@plurid/elementql-specification][elementql-specification] • specification\n\n[elementql-specification]: https://github.com/plurid/elementql/tree/master/packages/elementql-specification\n\n\n\n[@plurid/elementql-org][elementql-org] • documentation\n\n[elementql-org]: https://github.com/plurid/elementql/tree/master/packages/elementql-org\n\n\n\n## [Codeophon](https://github.com/ly3xqhl8g9/codeophon)\n\n+ licensing: [delicense](https://github.com/ly3xqhl8g9/delicense)\n+ versioning: [αver](https://github.com/ly3xqhl8g9/alpha-versioning)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplurid%2Felementql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplurid%2Felementql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplurid%2Felementql/lists"}