eoq3 v2.9.1
eoq3 - Essential Object Query version 3 core for JavaScript and TypeScript
This implements EOQ3 values, queries and commands in python. It includes domain wrappers that provide access to remote domains via HTTP or WebSocket. It does not contain a domain or MDB implementation.
Getting started example
These example implements the "Why EOQ?" example and some additional prints of model information.
Code is available as WhyWarehouseExample.ts / .js / .html at https://gitlab.com/eoq/js/jseoq/Examples/Eoq3/ .
Since eoq3 for JavaScript does not contain a domain implementation, a WebSocket server is required to be started externally, e.g. using e.g. pyeoq.
python -m pip install eoq3utils
python -m eoq3utils.services.wsdomaincli --enableSsl 0 --enableAccessControl 0
TypeScript
This example shows how to use eoq3 within a TypeScript program executed with npm + ts-node. Starting an external WebSocket Domain is prerequisite for this example to run.
- Install the dependencies
npm install eoq3
npm install typescript
npm install ts-node
- Create WhyWarehouse.ts with the following content
import { WebSocketDomainClient } from 'eoq3/domainwrappers';
import { Get, Set } from 'eoq3/command';
import { Cls, Pth } from 'eoq3/query';
import { TextSerializer } from 'eoq3/serializer';
import { CreateWarehouseM1Model, CreateWarehouseM2Model } from 'eoq3/examples/warehouse';
async function main() {
const ser = new TextSerializer();
// Initialize a local domain
const domain = new WebSocketDomainClient();
await domain.Connect('ws://localhost:5141');
// Init warehouse meta and user model
await CreateWarehouseM2Model(domain);
await CreateWarehouseM1Model(domain);
// Would you like to get a list of products?
let cmd = new Get(new Cls('Product'));
let products = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Products: ${ser.SerVal(products)}`);
// Would you like to know which one is sold less than 3-times?
cmd = new Get(new Cls('Product').Sel(new Pth('sells').Les(3)));
let badProducts = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Bad products: ${ser.SerVal(badProducts)}`);
// You might want to reduce their price by 10%?
cmd = new Get(new Cls('Product').Sel(new Pth('sells').Les(3)).Zip([new Pth('name'), new Pth('price')]));
let nameAndPrice = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Bad product prices: ${ser.SerVal(nameAndPrice)}`);
cmd = new Set(
new Cls('Product').Sel(new Pth('sells').Les(3)),
'price',
new Cls('Product').Sel(new Pth('sells').Les(3)).Pth('price').Mul(0.9)
);
let setConfirm = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Set confirm: ${ser.SerVal(setConfirm)}`);
// Re-read the prices
nameAndPrice = await domain.Do(new Get(new Cls('Product').Zip([new Pth('name'), new Pth('price')])));
console.log(`Product prices: ${ser.SerVal(nameAndPrice)}`);
// Would you like to see a list of the names of the categories of the badly selling products sorted ascending?
cmd = new Get(new Cls('Product').Sel(new Pth('sells').Les(3)).Met('PARENT').Pth('name').Uni([]).Idx('SORTASC'));
let badCategories = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Bad categories: ${ser.SerVal(badCategories)}`);
domain.Close();
}
main().catch(console.error);
- If not existing, create a TypeScript config file tsconfig.json with the following content.
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"sourceMap": true,
"resolveJsonModule": true,
}
}
- Execute WhyWarehouse.ts (do not forget to start the WebSocket server as mentioned above beforehand)
npx ts-node WhyWarehouseExample.ts
- You should see an output similar to this
GET (!Product)
Products: [(#y74),(#y79),(#y84),(#y89),(#y97),(#y102),(#y112),(#y117),(#y123),(#y128),(#y139),(#y144),(#y150),(#y155)]
GET (!Product{(/sells<l3))
Bad products: [(#y79),(#y89),(#y102),(#y112),(#y144),(#y155)]
GET (!Product{(/sells<l3)&ZIP[(/name),(/price)])
Bad product prices: [[Banana,f0.35],[Melon,f1.1],[Lettuce,f0.8],['Goat Cheese',f5],['Energy Drink',f10],['Hot Chocolate',f2.5]]
SET (!Product{(/sells<l3)) price (!Product{(/sells<l3)/price&MULf0.9)
Set confirm: [[(#y79),(#y89),(#y102),(#y112),(#y144),(#y155)],price,[f0.315,f0.9900000000000001,f0.7200000000000001,f4.5,f9,f2.25]]
Product prices: [[Apple,f0.25],[Banana,f0.315],[Orange,f0.45],[Melon,f0.9900000000000001],[Cucumber,f0.5],[Lettuce,f0.7200000000000001],['Goat Cheese',f4. 5],[Gouda,f2],[Cream,f0.5],[Milk,f0.6],[Coke,f1],['Energy Drink',f9],[Coffee,f2],['Hot Chocolate',f2.25]]
GET (!Product{(/sells<l3)@PARENT;[]/name&UNI[]:SORTASC)
Bad categories: [cheese,drinks,fruit,lemonade,vegetables]
JavaScript
This example shows how to use eoq3 within a stand-alone JavaScript program executed with node.js. Starting an external WebSocket Domain is prerequisite for this example to run.
Execute step 1 to 4 from the TypeScript section above
Compile WhyWarehouseExample.ts as JavaScript by running:
tsc
Take a look at WhyWarehouseExample.js
Execute WhyWarehouseExample.js (do not forget to start the WebSocket server as mentioned above beforehand)
node WhyWarehouseExample.js
HTML
This example shows how to use eoq3 embedded in a Website. Starting an external WebSocket Domain is prerequisite for this example to run.
- Create WhyWarehouseExample.html with following content:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>EOQ3 WhyWarehouseExample</title>
<script src="node_modules/eoq3/eoq3.min.js"></script> <!-- adapt path to eoq3.js as needed-->
<!-- <script src="../../eoq3/eoq3.min.js"></script> --> <!-- use this one for production -->
<script>
async function main() {
let ser = new eoq3.serializer.TextSerializer(); // eoq3.js requires eoq3... prefix
// Initialize a the WebSocket domain client
domain = new eoq3.domainwrappers.WebSocketDomainClient();
await domain.Connect('ws://localhost:5141');
await eoq3.examples.CreateWarehouseM2Model(domain);
await eoq3.examples.CreateWarehouseM1Model(domain);
// Would you like to get a list of products?
let cmd = CMD.Get(QRY.Cls('Product')); // use CMD shortcut to avoid 'new eoq3.command.Get(...), the same for QRY'
let products = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Products: ${ser.SerVal(products)}`);
// Would you like to know which one is sold less than 3-times?
cmd = CMD.Get(QRY.Cls('Product').Sel(QRY.Pth('sells').Les(3)));
let badProducts = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Bad products: ${ser.SerVal(badProducts)}`);
// You might want to reduce their price by 10%?
cmd = CMD.Get(QRY.Cls('Product').Sel(QRY.Pth('sells').Les(3)).Zip([QRY.Pth('name'), QRY.Pth('price')]));
let nameAndPrice = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Bad product prices: ${ser.SerVal(nameAndPrice)}`);
cmd = CMD.Set(
QRY.Cls('Product').Sel(QRY.Pth('sells').Les(3)),
'price',
QRY.Cls('Product').Sel(QRY.Pth('sells').Les(3)).Pth('price').Mul(0.9)
);
let setConfirm = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Set confirm: ${ser.SerVal(setConfirm)}`);
// Re-read the prices
nameAndPrice = await domain.Do(CMD.Get(QRY.Cls('Product').Zip([QRY.Pth('name'), QRY.Pth('price')])));
console.log(`Product prices: ${ser.SerVal(nameAndPrice)}`);
// Would you like to see a list of the names of the categories of the badly selling products sorted ascending?
cmd = CMD.Get(QRY.Cls('Product').Sel(QRY.Pth('sells').Les(3)).Met('PARENT').Pth('name').Uni([]).Idx('SORTASC'));
let badCategories = await domain.Do(cmd);
console.log(ser.SerCmd(cmd));
console.log(`Bad categories: ${ser.SerVal(badCategories)}`);
domain.Close();
}
</script>
</head>
<body onload="main()">
<h1>EOQ3 WhyWarehouseExample</h1>
<p>Open the console to see the results.</p>
</body>
</html>
- Open WhyWarehouseExample.html in a browser of your choice (do not forget to start the WebSocket server as mentioned above beforehand)
Documentation
For more information see EOQ3 documentation: https://eoq.gitlab.io/doc/eoq3/
jseoq main repository
jseoq sources can be found here: https://gitlab.com/eoq/js/jseoq
Author
2025 Bjoern Annighoefer