@plurid/elementql-client
v0.0.0-1
Published
ElementQL Client
Downloads
41
Readme
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
Current State
Consider the following Web Element which uses React
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
server can be installed running the command
npm install @plurid/elementql-server
or
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
// 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
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 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
curl http://localhost:21100/elementql \
-H "Content-Type: application/json" \
-v --data '{"elements":[{"name":"HelloElementQL"}]}'
ElementQL
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
# 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,
---
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
,
const elementQLServiceWorker = './node_modules/@plurid/elementql/distribution/service-worker.js';
importScripts(elementQLServiceWorker);
- creating and running the
metabootloader
,
const metabootloader = require('@plurid/elementql/distribution/metabootloader').default;
metabootloader();
- creating and running
useLibraries
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 theURL
for theElementQL
server endpoint, - and making the request with the
useEffect
,useState
standardReact
hooks, - or with the
useElementQL
custom hook.
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<any> = () => {
const Elements = useElementQL(
elementQLClient,
ElementQLJSONRequest,
'json',
);
return (
<>
{Elements && (
<Elements.HelloElementQL />
)}
</>
);
}
const App: React.FC<any> = () => {
const [Elements, setElements] = useState<any>();
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 && (
<Elements.HelloElementQL />
)}
</>
);
}
export default App;
Plugins
Babel
Uses Babel to transpile .js
and .jsx
element files.
TypeScript
Uses TypeScript to transpile .ts
and .tsx
element files.
Minify
Uses Terser to minify the element files.
Packages
@plurid/elementql • base
@plurid/elementql-client-react • react
client
@plurid/elementql-express • express
middleware
@plurid/elementql-server • NodeJS server
@plurid/elementql-server • Go server
@plurid/elementql-specification • specification
@plurid/elementql-org • documentation