feat: initial commit
This commit is contained in:
15
doc/README.md
Normal file
15
doc/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Documentation
|
||||
|
||||
## Edge Apps
|
||||
|
||||
Une **Edge App** est une application capable de s'exécuter dans un environnement "Edge".
|
||||
|
||||
### Référence
|
||||
|
||||
- [API Client](./apps/client-api/README.md)
|
||||
- [API Serveur](./apps/server-api/README.md)
|
||||
|
||||
### Tutoriels
|
||||
|
||||
- [Créer sa première application](./apps/my-first-app.md)
|
||||
- [Empaqueter une application](./apps/package-app.md)
|
64
doc/apps/client-api/README.md
Normal file
64
doc/apps/client-api/README.md
Normal file
@ -0,0 +1,64 @@
|
||||
# API Client
|
||||
|
||||
## Méthodes
|
||||
|
||||
### `Edge.connect(): Promise`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `Edge.disconnect(): void`
|
||||
|
||||
> `TODO`
|
||||
|
||||
|
||||
### `Edge.send(message: Object): void`
|
||||
|
||||
> `TODO`
|
||||
|
||||
|
||||
### `Edge.rpc(method: string, params: Object): Promise`
|
||||
|
||||
> `TODO`
|
||||
#### Exemple
|
||||
|
||||
**Côté serveur**
|
||||
|
||||
```js
|
||||
function onInit() {
|
||||
rpc.register(echo);
|
||||
}
|
||||
|
||||
function echo(ctx, params) {
|
||||
return params;
|
||||
}
|
||||
```
|
||||
|
||||
**Côté client**
|
||||
|
||||
```js
|
||||
Edge.connect().then(() => {
|
||||
Edge.rpc("echo", { hello: "world!" })
|
||||
.then(result => console.log(result))
|
||||
.catch(err => console.error(err));
|
||||
});
|
||||
```
|
||||
|
||||
### `Edge.upload(blob: Blob, metadata: Object): Promise`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `Edge.blobUrl(bucketName: string, blobId: string): string`
|
||||
|
||||
> `TODO`
|
||||
|
||||
## Événements
|
||||
|
||||
### `"message"`
|
||||
|
||||
> `TODO`
|
||||
|
||||
#### Exemple
|
||||
|
||||
```js
|
||||
Edge.addEventListener("message", evt => console.log(evt.detail));
|
||||
```
|
103
doc/apps/my-first-app.md
Normal file
103
doc/apps/my-first-app.md
Normal file
@ -0,0 +1,103 @@
|
||||
# Créer ma première application
|
||||
|
||||
## 1. Télécharger le CLI
|
||||
|
||||
1. Se rendre à l'adresse https://forge.cadoles.com/arcad/edge/releases
|
||||
|
||||
2. Télécharger la dernière version du binaire `cli` disponible dans la page.
|
||||
|
||||
## 2. Créer l'arborescence de son application
|
||||
|
||||
L'arborescence d'une "Edge App" doit correspondre à une structure prédéfinie.
|
||||
|
||||
```bash
|
||||
my-app
|
||||
|-> manifest.yml # Le fichier "manifeste" décrivant votre application
|
||||
|-> public # Répertoire contenant tous les fichiers accessibles publiquement
|
||||
|-> server
|
||||
|-> main.js # Le point d'entrée pour le code "serveur" de votre application
|
||||
```
|
||||
|
||||
## 3. Compléter le fichier `manifest.yml`
|
||||
|
||||
Ce fichier est le manifeste de votre application. Il permet au serveur d'identifier celle ci et de récupérer des informations la concernant.
|
||||
|
||||
```yaml
|
||||
---
|
||||
# L'identifiant de votre application. Il doit être globalement unique.
|
||||
# Un identifiant du type nom de domaine inversé est en général conseillé (ex: tld.mycompany.myapp)
|
||||
id: tld.mycompany.myapp
|
||||
|
||||
# Le titre de votre application.
|
||||
title: My App
|
||||
|
||||
# Les mots-clés associés à votre applications.
|
||||
tags: ["chat"]
|
||||
|
||||
# La description de votre application.
|
||||
# Vous pouvez utiliser la syntaxe Markdown pour la mettre en forme.
|
||||
description: |>
|
||||
A simple demo application
|
||||
```
|
||||
|
||||
## 4. Créer la page d'accueil
|
||||
|
||||
Créer le fichier `my-app/public/index.html`:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
<title>My App</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My App</h1>
|
||||
<!-- Inclure le SDK -->
|
||||
<script type="text/javascript" src="/edge/sdk/client.js"></script>
|
||||
<script type="text/javascript">
|
||||
// On utilise le SDK via la variable globale "Edge"
|
||||
// pour se connecter au serveur de notre application.
|
||||
Edge.connect().then(() => {
|
||||
// Une fois connecté, on envoie un message au serveur.
|
||||
Edge.send({ "hello": "world" });
|
||||
});
|
||||
|
||||
// On écoute les messages en provenance du serveur.
|
||||
Edge.addEventListener("message", (evt) => {
|
||||
console.log("New server message", evt.detail)
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## 5. Créer le fichier `server/main.js`
|
||||
|
||||
Ce fichier est nécessaire, même vide.
|
||||
|
||||
```javascript
|
||||
// La fonction "onInit()" (si déclarée) est automatiquement
|
||||
// exécutée au démarrage du serveur de votre application.
|
||||
function onInit() {
|
||||
|
||||
}
|
||||
|
||||
// La fonction "onClientMessage(ctx, message)" est automatiquement
|
||||
// exécutée quand le serveur de votre application reçoit un
|
||||
// message en provenance du client.
|
||||
function onClientMessage(ctx, message) {
|
||||
console.log(message);
|
||||
|
||||
// On utilise le module "net" pour renvoyer un message au client
|
||||
net.send(ctx, { "my": "message" });
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Exécuter votre application en local
|
||||
|
||||
Utiliser le CLI téléchargé préalablement pour lancer votre nouvelle application localement.
|
||||
|
||||
```bash
|
||||
cli app run -p ./chemin/vers/app
|
||||
```
|
||||
|
||||
La page d'accueil devrait être accessible à l'adresse http://localhost:8080.
|
3
doc/apps/package-app.md
Normal file
3
doc/apps/package-app.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Empaqueter une application
|
||||
|
||||
> `TODO`
|
28
doc/apps/server-api/README.md
Normal file
28
doc/apps/server-api/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# API Serveur
|
||||
|
||||
## Fonctions de rappel
|
||||
|
||||
### `onInit(): void`
|
||||
|
||||
Cette méthode est automatiquement exécutée au démarrage du serveur de l'application.
|
||||
|
||||
Comme son nom l'indique, elle permet d'exécuter des opérations d'initialisation de votre application.
|
||||
|
||||
#### Exemple
|
||||
|
||||
```js
|
||||
function onInit() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Modules
|
||||
|
||||
Listes des modules disponibles côté serveur.
|
||||
|
||||
- [`console`](./console.md)
|
||||
- [`context`](./context.md)
|
||||
- [`net`](./net.md)
|
||||
- [`rpc`](./rpc.md)
|
||||
- [`store`](./store.md)
|
||||
- [`blob`](./blob.md)
|
73
doc/apps/server-api/blob.md
Normal file
73
doc/apps/server-api/blob.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Module `blob`
|
||||
|
||||
Ce module permet de manipuler des fichiers ("blobs") au sein de votre application.
|
||||
|
||||
## Fonctions de rappel
|
||||
|
||||
Pour permettre aux utilisateurs de téléverser/télécharger des fichiers ("blobs") dans votre application, il vous faudra déclarer 2 fonctions dans votre fichier `server/main.js`.
|
||||
|
||||
### `onBlobUpload(ctx: Context, blobId: string, blobInfo: BlobInfo, metadata: Metadata)`
|
||||
|
||||
> `TODO`
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onBlobUpload(ctx, blobId, blobInfo, metadata) {
|
||||
// Autoriser le téléversement et indiquer que le fichier doit être stocké dans le bucket "my-bucket"
|
||||
return { allow: true, bucket: "my-bucket" };
|
||||
}
|
||||
```
|
||||
|
||||
### `onBlobDownload(ctx: Context, bucketName: string, blobId: string)`
|
||||
|
||||
> `TODO`
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onBlobDownload(ctx, bucketName, blobId) {
|
||||
// Autoriser le téléchargement
|
||||
return { allow: true };
|
||||
}
|
||||
```
|
||||
|
||||
## Méthodes
|
||||
|
||||
### `blob.listBuckets(ctx: Context): string[]`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `blob.writeBlob(ctx: Context, bucketName: string, blobId: string)`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `blob.readBlob(ctx: Context, bucketName: string, blobId: string)`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `blob.listBlobs(ctx: Context, bucketName: string): BlobInfo[]`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `blob.deleteBlob(ctx: Context, bucketName: string, blobId: string)`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `blob.deleteBucket(ctx: Context, bucketName: string)`
|
||||
|
||||
> `TODO`
|
||||
|
||||
### `blob.getBlobInfo(ctx: Context, bucketName: string, blobId: string): BlobInfo`
|
||||
|
||||
> `TODO`
|
||||
|
||||
## Objets
|
||||
|
||||
### `Context`
|
||||
|
||||
Voir la documentation de l'objet [`Context`](./context.md#Context).
|
||||
|
||||
### `BlobInfo`
|
||||
|
||||
### `Metadata`
|
3
doc/apps/server-api/console.md
Normal file
3
doc/apps/server-api/console.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Module `console`
|
||||
|
||||
> `TODO`
|
74
doc/apps/server-api/context.md
Normal file
74
doc/apps/server-api/context.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Module `context`
|
||||
|
||||
Ce module permet de manipuler les informations de contexte liées à la réception de messages ou à l'utilisation de certains autres modules.
|
||||
|
||||
## Méthodes
|
||||
|
||||
### `context.new(): Context`
|
||||
|
||||
Renvoie un nouveau contexte vide.
|
||||
|
||||
#### Arguments
|
||||
|
||||
Aucun
|
||||
#### Valeur de retour
|
||||
|
||||
Un nouvel objet de contexte.
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
var ctx = context.new();
|
||||
```
|
||||
|
||||
### `context.get(ctx: Context, key: string): any|null`
|
||||
|
||||
Récupère la valeur associée à la clé `key` dans le contexte si celle ci existe.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `ctx` **Context** Contexte duquel extraire la valeur souhaitée
|
||||
- `key` **string** Clé associé à la valeur à récupérer
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
Valeur associée à la clé ou `null`.
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onClientMessage(ctx, message) {
|
||||
var sessionId = context.get(ctx, "mykey");
|
||||
console.log(sessionId);
|
||||
}
|
||||
```
|
||||
|
||||
## Propriétés
|
||||
|
||||
### `context.SESSION_ID`
|
||||
|
||||
Clé permettant de récupérer la clé de session associé au client émetteur du message courant.
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onClientMessage(ctx, message) {
|
||||
var sessionId = context.get(ctx, context.SESSION_ID);
|
||||
console.log(sessionId);
|
||||
}
|
||||
```
|
||||
|
||||
### `context.ORIGINAL_REQUEST`
|
||||
|
||||
Clé permettant de récupérer la requête HTTP à l'origine de la connexion du client.
|
||||
|
||||
_Cette propriété est utilisée par le module [`auth`](./auth.md) pour récupérer l'utilisateur associé au client._
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onClientMessage(ctx, message) {
|
||||
var request = context.get(ctx, context.ORIGINAL_REQUEST);
|
||||
console.log(request);
|
||||
}
|
||||
```
|
63
doc/apps/server-api/net.md
Normal file
63
doc/apps/server-api/net.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Module `net`
|
||||
|
||||
Ce module permet d'envoyer des messages aux clients connectés au serveur.
|
||||
|
||||
## Fonctions de rappel
|
||||
|
||||
### `onClientMessage(ctx: Context, msg: Message)`
|
||||
|
||||
Cette méthode est appelée pour chaque message reçu par le serveur depuis un client connecté.
|
||||
|
||||
> `TODO`
|
||||
|
||||
## Méthodes
|
||||
|
||||
### `net.send(ctx: string|Context, data: Object): void`
|
||||
|
||||
Envoie un message au client connecté au serveur.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `ctx` **string|Context** Identifiant de session du client ou contexte portant l'identifiant de session du client. Voir la documentation du module [`context`](./context.md).
|
||||
- `data` **Object** Données à envoyer au client
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
Aucune
|
||||
|
||||
#### Usage
|
||||
|
||||
**Côté client**
|
||||
|
||||
```js
|
||||
// Les données envoyées par le serveur sont accessibles
|
||||
// via la propriété evt.detail.
|
||||
Edge.on('message', evt => console.log(evt.detail));
|
||||
|
||||
Edge.connect();
|
||||
```
|
||||
|
||||
**Côté serveur**
|
||||
|
||||
```js
|
||||
function onInit() {
|
||||
var ctx = context.background();
|
||||
net.send(ctx, {"foo", "bar"});
|
||||
}
|
||||
```
|
||||
|
||||
### `net.broadcast(data: Object): void`
|
||||
|
||||
Envoie un message à l'ensemble des clients connectés au serveur.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `data` **object** Données à envoyer aux clients connectés
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
Aucune
|
||||
|
||||
#### Usage
|
||||
|
||||
Voir usage `net.send()`.
|
43
doc/apps/server-api/rpc.md
Normal file
43
doc/apps/server-api/rpc.md
Normal file
@ -0,0 +1,43 @@
|
||||
# Module `rpc`
|
||||
|
||||
Ce module permet de déclarer des méthodes côté serveur qui seront "invoquable" côté client via la méthode [`Edge.rpc(method: string, params: Object): Promise`](../client-api/README.md#edgerpcmethod-string-params-object-promise).
|
||||
|
||||
## Méthodes
|
||||
|
||||
### `rpc.register(name: string, cb?: Function): void`
|
||||
|
||||
Marque une fonction comme étant appelable par le client.
|
||||
#### Arguments
|
||||
|
||||
- `name` **string** Le nom de la fonction telle qu'elle sera appelable par le client. Si `cb` n'est pas spécifié, la fonction portant le même nom est utilisée.
|
||||
- `cb` **Function** Référence de la fonction à exécuter.
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
Aucune
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onInit() {
|
||||
rpc.register("echo", echo);
|
||||
}
|
||||
|
||||
function echo(ctx, params) {
|
||||
return params;
|
||||
}
|
||||
```
|
||||
|
||||
**Côté client**
|
||||
|
||||
```js
|
||||
Edge.connect().then(() => {
|
||||
Edge.rpc("echo", { hello: "world!" })
|
||||
.then(result => console.log(result))
|
||||
.catch(err => console.error(err));
|
||||
});
|
||||
```
|
||||
|
||||
### `rpc.unregister(name: string): void`
|
||||
|
||||
> `TODO`
|
183
doc/apps/server-api/store.md
Normal file
183
doc/apps/server-api/store.md
Normal file
@ -0,0 +1,183 @@
|
||||
# Module `store`
|
||||
|
||||
Ce module permet de stocker et récupérer des données structurées ("documents") sur le serveur.
|
||||
|
||||
## Méthodes
|
||||
|
||||
### `store.upsert(ctx: Context, collection: string, doc: Object)`
|
||||
|
||||
Enregistre un document dans une collection.
|
||||
|
||||
Si le document a une propriété `_id` celle ci est utilisée comme identifiant. Dans le cas contraire elle sera autogénérée par le moteur de stockage.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `ctx` **Context** Le contexte d'exécution. Voir la documentation du module [`context`](./context.md)
|
||||
- `collection` **string** Nom de la collection dans laquelle retrouver le document
|
||||
- `doc` **Object** Le document à enregistrer
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
Le document dans sa forme après enregistrement.
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
var ctx = context.new();
|
||||
var obj = store.upsert(ctx, "myCollection", {"foo": "bar"});
|
||||
```
|
||||
|
||||
### `store.get(ctx: Context, collection: string, docId: string)`
|
||||
|
||||
Retourne le document associé à l'identifiant `docId` ou `null` si celui ci n'est pas trouvé.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `ctx` **Context** Le contexte d'exécution. Voir la documentation du module [`context`](./context.md)
|
||||
- `collection` **string** Nom de la collection dans laquelle retrouver le document
|
||||
- `docId` **string** Identifiant du document à récupérer
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
le document stocké si il existe, `null` sinon.
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
function onInit() {
|
||||
var ctx = context.new();
|
||||
var obj = store.get(ctx, "myCollection", "doc-id");
|
||||
}
|
||||
```
|
||||
|
||||
### `store.delete(ctx: Context, collection: string, docId: string)`
|
||||
|
||||
Supprime le document associé à l'identifiant dans la collection.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `ctx` **Context** Le contexte d'exécution. Voir la documentation du module [`context`](./context.md)
|
||||
- `collection` **string** Nom de la collection dans laquelle retrouver le document
|
||||
- `docId` **string** Identifiant de le document à supprime
|
||||
|
||||
#### Valeur de retour
|
||||
|
||||
Aucune
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
var ctx = context.new();
|
||||
store.delete(ctx, "myCollection", "my-item-id");
|
||||
```
|
||||
|
||||
### `store.query(ctx: Context, collection: string, doc: Object, filter: Filter?, options: QueryOptions?)`
|
||||
|
||||
Filtre la collection et récupère les documents associés à la requête.
|
||||
|
||||
#### Arguments
|
||||
|
||||
- `ctx` **Context** Le contexte d'exécution. Voir la documentation du module [`context`](./context.md)
|
||||
- `collection` **string** Nom de la collection dans laquelle retrouver le document
|
||||
- `filter` **Filter?** Filtre à appliquer à la collection, voir "Filtres".
|
||||
- `options` **QueryOptions?** Options de filtrage, voir "Options".
|
||||
|
||||
|
||||
## Propriétés
|
||||
|
||||
### `store.DIRECTION_ASC`
|
||||
|
||||
> `TODO`
|
||||
### `store.DIRECTION_DESC`
|
||||
|
||||
> `TODO`
|
||||
|
||||
## Objets
|
||||
|
||||
### `Filter`
|
||||
|
||||
Un filtre se construit à partir d'une hiérarchie d'opérateurs sous la forme d'un document.
|
||||
|
||||
On distingue deux types d'opérateurs:
|
||||
|
||||
- Les opérateurs de combinaison logique;
|
||||
- Les opérateurs de filtrage.
|
||||
|
||||
Les opérateurs d'combinaison logique prennent la forme suivante:
|
||||
|
||||
```
|
||||
{
|
||||
"<comb_op>": [
|
||||
<filter_op>,
|
||||
<filter_op>,
|
||||
etc
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Exemple**
|
||||
|
||||
```json
|
||||
{
|
||||
"and": [
|
||||
{ "eq": { "myAttr1": "foo" } },
|
||||
{ "neq": { "myAttr2": "bar" } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Ce filtre serait traduit en syntaxe SQL en `myAttr1 = "foo" AND myAttr2 != "bar"`.
|
||||
|
||||
Voici la liste des opérateurs de combinaison logique:
|
||||
|
||||
- `and` - "ET" logique
|
||||
- `or` - "OU" logique
|
||||
- `not` - Négation logique
|
||||
|
||||
Les opérateurs de filtrage prennent la forme suivantes:
|
||||
|
||||
```
|
||||
{
|
||||
<filter_op>: {
|
||||
"key1": "val1",
|
||||
"key2": "val2",
|
||||
"key3": "val3",
|
||||
etc
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Exemple**
|
||||
|
||||
```json
|
||||
{ "gt": { "foo": "bar" } },
|
||||
```
|
||||
|
||||
Voici la liste des opérateurs de filtrage:
|
||||
|
||||
- `eq` - Comparaison `==`
|
||||
- `neq` - Comparaison `!=`
|
||||
- `gt` - Comparaison `>`
|
||||
- `gte` - Comparaison `>=`
|
||||
- `lt` - Comparaison `<`
|
||||
- `lte` - Comparaison `<=`
|
||||
- `like` - Comparaison type `LIKE` MySQL/SQLite
|
||||
- `in` - Comparaison type `IN` MySQL/SQLite
|
||||
|
||||
### QueryOptions
|
||||
|
||||
#### Usage
|
||||
|
||||
```js
|
||||
var ctx = context.new();
|
||||
var results = store.query(ctx, "myCollection", {
|
||||
eq: {
|
||||
"foo": "bar",
|
||||
}
|
||||
}, {
|
||||
limit: 10,
|
||||
offset: 5,
|
||||
orderBy: "foo",
|
||||
orderDirection: store.ASC,
|
||||
});
|
||||
```
|
Reference in New Issue
Block a user