Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/plurid/elementql
Query Web Elements at Runtime
https://github.com/plurid/elementql
element query-language web
Last synced: about 7 hours ago
JSON representation
Query Web Elements at Runtime
- Host: GitHub
- URL: https://github.com/plurid/elementql
- Owner: plurid
- License: other
- Created: 2019-09-07T04:21:31.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-04-26T13:48:37.000Z (over 1 year ago)
- Last Synced: 2024-10-29T22:26:06.780Z (9 days ago)
- Topics: element, query-language, web
- Language: TypeScript
- Homepage: https://elements.plurid.cloud
- Size: 4.69 MB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
ElementQL
Query Web Elements
`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.
### Contents
+ [Description](#description)
+ [Current State](#current-state)
+ [ElementQL Proposal](#elementql-proposal)
+ [Usage](#usage)
+ [Server](#server)
+ [NodeJS](#nodejs)
+ [Go](#go)
+ [Python](#python)
+ [Client](#client)
+ [React](#react)
+ [Plugins](#plugins)
+ [Babel](#babel)
+ [TypeScript](#typescript)
+ [Minify](#minify)
+ [Packages](#packages)
+ [Codeophon](#codeophon)## Description
### Current State
Consider the following Web Element which uses [React](https://reactjs.org/)
``` typescript
const HelloElementQL = () => {
return React.createElement('div', null, 'Hello from ElementQL');
}
```When embedded into a standard `React` rendering process, the `HelloElementQL` functional element will generate a `div` containing the text `Hello from ElementQL`.
The 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.
### ElementQL Proposal
The 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.
## Usage
### Server
#### NodeJS
##### Install
The [`NodeJS`](https://nodejs.org) server can be installed running the command
``` bash
npm install @plurid/elementql-server
```or
``` bash
yarn add @plurid/elementql-server
```##### Start
The simplest `ElementQL` server requires only to be started, the elements will be served from the default `./elements` path
``` typescript
// server.js
import ElementQLServer from '@plurid/elementql-server';const server = new ElementQLServer();
server.start();
```The server will then accept requests on the `http://localhost:21100/elementql` URL for the elements in the `./elements` directory.
##### Elements
The `./elements` directory has a structure of folders with element-specific files: `.js`, `.jsx`, `.ts`, `.tsx`, or `.css`. For example
```
.
|- server.js
|- elements
| |- HelloElementQL
| | |- index.js
| |-
|-
```##### Options
The `ElementQLServer` Object can receive an options object
``` typescript
import {
ElementQLServerOptions,
} from '@plurid/elementql-server';/** defaults */
const options: ElementQLServerOptions = {
protocol: 'https', /** default for production; for development: `'http'` */
domain: '', /** the domain for the server, e.g. example.com */
/** will be used to resolve elements relative and library imports */
port: 21100,rootDirectory: process.cwd(),
buildDirectory: 'build', /** relative to the root directory */
nodeModulesDirectory: 'node_modules', /** relative to the root directory */
elementqlDirectory: '.elementql', /** relative to the build directory */
transpilesDirectory: 'transpiles', /** relative to the elementql directory */elementsDirectories: [ /**/
'elements', /** relative to the build directory */
], /**/
libraries: {},
endpoint: '/elementql',
allowOrigin: ['*'],
allowHeaders: ['*'],
plugins: [ /**/
'minify', /** default for production; for development: `[]` */
], /**/verbose: true,
open: true,
playground: false,
playgroundEndpoint: '/playground',store: null,
metadataFilename: 'metadata.json',
};
```##### Requests
In 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
JSON
``` bash
curl http://localhost:21100/elementql \
-H "Content-Type: application/json" \
-v --data '{"elements":[{"name":"HelloElementQL"}]}'
```ElementQL
``` bash
curl http://localhost:21100/elementql \
-H "Content-Type: application/elementql" \
-v --data 'elements{HelloElementQL}'
```##### Metadata
In each element directory there can be an `elementql.yaml` file with metadata specific to the element
``` yaml
# the element name derived from the directory name will be overwrriten with `OverwriteName`
name: OverwriteName
```#### Go
The `elementql-server` for `Go` is a `go 1.14` module.
#### Python
### Client
#### React
Considering the standard `React` application, using `ElementQL` involves
+ creating an `elementql.yaml` configuration file,
``` yaml
---
globals:
react: React
react-dom: ReactDOM
origins:
elementql: http://localhost:21100/elementql
application: http://localhost:8005
bootloader: './source/index.js'
entry: './app/index.js'
```+ creating the `service-worker`,
``` js
const elementQLServiceWorker = './node_modules/@plurid/elementql/distribution/service-worker.js';importScripts(elementQLServiceWorker);
```+ creating and running the `metabootloader`,
``` js
const metabootloader = require('@plurid/elementql/distribution/metabootloader').default;metabootloader();
```+ creating and running `useLibraries`
``` js
const {
libraries,
useLibraries,
} = require('@plurid/elementql');const usedLibraries = {
react: libraries.react,
reactDom: libraries.reactDom,
};const buildDirectory = 'build';
useLibraries({
libraries: usedLibraries,
buildDirectory,
});
```+ defining an `ElementQL`/`JSON` request,
+ instantiating an `ElementQLClient` with the `URL` for the `ElementQL` server endpoint,
+ and making the request with the `useEffect`, `useState` standard `React` hooks,
+ or with the `useElementQL` custom hook.``` tsx
import React, {
useEffect,
useState,
} from 'react';import ElementQLClientReact, {
useElementQL,
} from '@plurid/elementql-client-react';const elementQLClient = new ElementQLClientReact({
url: 'http://localhost:21100/elementql',
});const ElementQLJSONRequest = {
elements: [
{
name: 'HelloElementQL',
},
],
};const AppWithHook: React.FC = () => {
const Elements = useElementQL(
elementQLClient,
ElementQLJSONRequest,
'json',
);return (
<>
{Elements && (
)}
>
);
}const App: React.FC = () => {
const [Elements, setElements] = useState();useEffect(() => {
let mounted = true;const fetchElements = async () => {
const {
status,
Elements,
}: any = await elementQLClient.get(
ElementQLJSONRequest,
'json',
);if (!status || !mounted) {
return;
}setElements(Elements);
}fetchElements();
return () => {
mounted = false;
}
}, []);return (
<>
{Elements && (
)}
>
);
}export default App;
```## Plugins
### Babel
Uses [Babel](https://github.com/babel/babel) to transpile `.js` and `.jsx` element files.
### TypeScript
Uses [TypeScript](https://github.com/microsoft/TypeScript) to transpile `.ts` and `.tsx` element files.
### Minify
Uses [Terser](https://github.com/terser/terser) to minify the element files.
## Packages
[@plurid/elementql][elementql] • base
[elementql]: https://github.com/plurid/elementql/tree/master/packages/elementql
[@plurid/elementql-client][elementql-client]
[elementql-client]: https://github.com/plurid/elementql/tree/master/packages/elementql-client
[@plurid/elementql-client-react][elementql-client-react] • `react` client
[elementql-client-react]: https://github.com/plurid/elementql/tree/master/packages/elementql-client-react
[@plurid/elementql-express][elementql-express] • `express` middleware
[elementql-express]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-express
[@plurid/elementql-parser][elementql-parser]
[elementql-parser]: https://github.com/plurid/elementql/tree/master/packages/elementql-parser
[@plurid/elementql-server][elementql-server-node] • NodeJS server
[elementql-server-node]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-node
[@plurid/elementql-server][elementql-server-go] • Go server
[elementql-server-go]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-go
[@plurid/elementql-specification][elementql-specification] • specification
[elementql-specification]: https://github.com/plurid/elementql/tree/master/packages/elementql-specification
[@plurid/elementql-org][elementql-org] • documentation
[elementql-org]: https://github.com/plurid/elementql/tree/master/packages/elementql-org
## [Codeophon](https://github.com/ly3xqhl8g9/codeophon)
+ licensing: [delicense](https://github.com/ly3xqhl8g9/delicense)
+ versioning: [αver](https://github.com/ly3xqhl8g9/alpha-versioning)