Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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

Awesome Lists containing this project

README

        










License: DEL


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


Version

[@plurid/elementql][elementql] • base

[elementql]: https://github.com/plurid/elementql/tree/master/packages/elementql


Version

[@plurid/elementql-client][elementql-client]

[elementql-client]: https://github.com/plurid/elementql/tree/master/packages/elementql-client


Version

[@plurid/elementql-client-react][elementql-client-react] • `react` client

[elementql-client-react]: https://github.com/plurid/elementql/tree/master/packages/elementql-client-react


Version

[@plurid/elementql-express][elementql-express] • `express` middleware

[elementql-express]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-express


Version

[@plurid/elementql-parser][elementql-parser]

[elementql-parser]: https://github.com/plurid/elementql/tree/master/packages/elementql-parser


Version

[@plurid/elementql-server][elementql-server-node] • NodeJS server

[elementql-server-node]: https://github.com/plurid/elementql/tree/master/packages/elementql-server-node


Version

[@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)