chore(js-client): Update and restructure examples [fixes DXJ-454] (#464)
* Update examples * Update js-client examples * Add cli to example * Fixes * Update js-client * Update js-client version in js-client examples * PR fixes * Remove marine-js * Update locks * Fix aqua * Remove unused import * Adjust import * Change code comment * Update example structures * Fix quickstart examples * Add aqua command to README * Add marine example * Fix image links * Fixes * Misc fixes
2
.github/workflows/js-projects.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
with:
|
||||
files: |
|
||||
quickstart/1-browser-to-browser
|
||||
quickstart/3-browser-to-service
|
||||
quickstart/2-browser-parallel-computation
|
||||
js-client-examples/hello-world
|
||||
js-client-examples/browser-example
|
||||
js-client-examples/node-example
|
||||
|
779
js-client-examples/browser-example/.fluence/schemas/fluence.json
Normal file
@ -0,0 +1,779 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "A map with service names as keys and Service configs as values. You can have any number of services listed here as long as service name keys start with a lowercase letter and contain only letters numbers and underscores. You can use `fluence service add` command to add a service to this config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Service_name": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 5
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"title": "Dependencies",
|
||||
"nullable": true,
|
||||
"description": "(For advanced users) Overrides for the project dependencies",
|
||||
"properties": {
|
||||
"npm": {
|
||||
"type": "object",
|
||||
"title": "npm dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of npm aqua dependency versions. Fluence CLI ensures dependencies are installed each time you run aqua",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"npm_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "npm dependency version"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"cargo": {
|
||||
"type": "object",
|
||||
"title": "Cargo dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of cargo dependency versions. Fluence CLI ensures dependencies are installed each time you run commands that depend on Marine or Marine REPL",
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Cargo_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "cargo dependency version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaInputPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the aqua file or directory with aqua files that you want to compile by default. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputTSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to ts. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputJSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to js. Must be relative to the project root dir. Overrides 'aquaOutputTSPath' property"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a list of peer IDs to host the worker on. Intended to be used by providers to deploy directly without using the blockchain",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"workerName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"deals": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a deal",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"dealName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"spells": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "A map with spell names as keys and spell configs as values",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Spell_name": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaImports": {
|
||||
"type": "array",
|
||||
"description": "A list of path to be considered by aqua compiler to be used as imports. First dependency in the list has the highest priority. Priority of imports is considered in the following order: imports from --import flags, imports from aquaImports property in fluence.yaml, project's .fluence/aqua dir, npm dependencies from fluence.yaml, npm dependencies from user's .fluence/config.yaml, npm dependencies recommended by fluence",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"marineBuildArgs": {
|
||||
"type": "string",
|
||||
"description": "Space separated `cargo build` flags and args to pass to marine build. Can be overridden using --marine-build-args flag Default: --release",
|
||||
"nullable": true
|
||||
},
|
||||
"cliVersion": {
|
||||
"type": "string",
|
||||
"description": "The version of the Fluence CLI that is compatible with this project. Set this to enforce a particular set of versions of all fluence components",
|
||||
"nullable": true
|
||||
},
|
||||
"ipfsAddr": {
|
||||
"type": "string",
|
||||
"description": "IPFS multiaddress to use when uploading workers with 'deal deploy'. Default: /dns4/ipfs.fluence.dev/tcp/5001 or /ip4/127.0.0.1/tcp/5001 if using local local env (for 'workers deploy' IPFS address provided by relay that you are connected to is used)",
|
||||
"nullable": true,
|
||||
"default": "/dns4/ipfs.fluence.dev/tcp/5001"
|
||||
},
|
||||
"customFluenceEnv": {
|
||||
"type": "object",
|
||||
"description": "Custom Fluence environment to use when connecting to Fluence network",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"contractsEnv": {
|
||||
"type": "string",
|
||||
"description": "Contracts environment to use for this fluence network to sign contracts on the blockchain",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"relays": {
|
||||
"type": "array",
|
||||
"description": "List of custom relay multiaddresses to use when connecting to Fluence network",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contractsEnv",
|
||||
"relays"
|
||||
]
|
||||
},
|
||||
"defaultSecretKeyName": {
|
||||
"description": "Secret key with this name will be used by default by js-client inside CLI to run Aqua code",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"relaysPath": {
|
||||
"description": "Path to the directory where you want relays.json file to be generated. Must be relative to the project root dir. This file contains a list of relays to use when connecting to Fluence network and depends on the default environment that you use in your project",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"$id": "https://fluence.dev/schemas/fluence.yaml",
|
||||
"title": "fluence.yaml",
|
||||
"description": "Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project"
|
||||
}
|
@ -2,18 +2,26 @@
|
||||
|
||||
This sample project demonstrates how fluence network can be accessed from the browser. As an example it retrieves the timestamp of the current time from the relay node. The project is based on an create-react-app template with slight modifications to integrate Fluence. The primary focus is the integration itself, i.e React could be swapped with a framework of your choice.
|
||||
|
||||
> To run this example you need `@latest` version of Fluence CLI. You can find installation guide [here](https://github.com/fluencelabs/cli).
|
||||
|
||||
## Getting started
|
||||
|
||||
Go to `src/frontend` folder:
|
||||
|
||||
```bash
|
||||
cd ./src/frontend
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
```
|
||||
|
||||
Run aqua compiler in watch mode:
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
npm run watch-aqua
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
Start the application
|
||||
|
13
js-client-examples/browser-example/fluence.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
@ -24,7 +24,7 @@ yarn-error.log*
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
src/compiled-aqua/*
|
||||
|
||||
public/*.wasm
|
||||
public/runnerScript.*
|
@ -3,8 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client.api": "0.13.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.1.2",
|
||||
"@fluencelabs/js-client": "^0.5.4",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
@ -20,15 +19,11 @@
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
@ -51,8 +46,6 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/cli": "0.9.1",
|
||||
"@fluencelabs/aqua-lib": "0.7.7",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"jest-puppeteer": "^6.0.2",
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -1,21 +1,21 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.scss';
|
||||
import relays from './relays.json';
|
||||
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
||||
import { getRelayTime } from './_aqua/getting-started';
|
||||
import { Fluence, type ConnectionState } from '@fluencelabs/js-client';
|
||||
import { getRelayTime } from './compiled-aqua/getting-started';
|
||||
|
||||
const relayNode = krasnodar[0];
|
||||
const relayNode = relays[0];
|
||||
|
||||
function App() {
|
||||
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||
const [relayTime, setRelayTime] = useState<Date | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
Fluence.onConnectionStateChange((state) => {
|
||||
setConnectionState(state);
|
||||
setConnectionState('connecting');
|
||||
Fluence.connect(relays[0]).then(() => {
|
||||
setConnectionState('connected');
|
||||
});
|
||||
}, []);
|
||||
|
||||
@ -23,7 +23,6 @@ function App() {
|
||||
if (connectionState !== 'connected') {
|
||||
return;
|
||||
}
|
||||
|
||||
const time = await getRelayTime(relayNode.peerId);
|
||||
setRelayTime(new Date(time));
|
||||
};
|
@ -3,13 +3,6 @@ import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import { randomKras } from '@fluencelabs/fluence-network-environment';
|
||||
|
||||
const relayNode = randomKras();
|
||||
|
||||
Fluence.connect(relayNode);
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"multiaddr": "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e",
|
||||
"peerId": "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51",
|
||||
"peerId": "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"peerId": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"peerId": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
"peerId": "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
"peerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
"peerId": "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"peerId": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn",
|
||||
"peerId": "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"peerId": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm",
|
||||
"peerId": "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm"
|
||||
}
|
||||
]
|
779
js-client-examples/hello-world/.fluence/schemas/fluence.json
Normal file
@ -0,0 +1,779 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "A map with service names as keys and Service configs as values. You can have any number of services listed here as long as service name keys start with a lowercase letter and contain only letters numbers and underscores. You can use `fluence service add` command to add a service to this config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Service_name": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 5
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"title": "Dependencies",
|
||||
"nullable": true,
|
||||
"description": "(For advanced users) Overrides for the project dependencies",
|
||||
"properties": {
|
||||
"npm": {
|
||||
"type": "object",
|
||||
"title": "npm dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of npm aqua dependency versions. Fluence CLI ensures dependencies are installed each time you run aqua",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"npm_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "npm dependency version"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"cargo": {
|
||||
"type": "object",
|
||||
"title": "Cargo dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of cargo dependency versions. Fluence CLI ensures dependencies are installed each time you run commands that depend on Marine or Marine REPL",
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Cargo_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "cargo dependency version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaInputPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the aqua file or directory with aqua files that you want to compile by default. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputTSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to ts. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputJSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to js. Must be relative to the project root dir. Overrides 'aquaOutputTSPath' property"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a list of peer IDs to host the worker on. Intended to be used by providers to deploy directly without using the blockchain",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"workerName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"deals": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a deal",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"dealName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"spells": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "A map with spell names as keys and spell configs as values",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Spell_name": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaImports": {
|
||||
"type": "array",
|
||||
"description": "A list of path to be considered by aqua compiler to be used as imports. First dependency in the list has the highest priority. Priority of imports is considered in the following order: imports from --import flags, imports from aquaImports property in fluence.yaml, project's .fluence/aqua dir, npm dependencies from fluence.yaml, npm dependencies from user's .fluence/config.yaml, npm dependencies recommended by fluence",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"marineBuildArgs": {
|
||||
"type": "string",
|
||||
"description": "Space separated `cargo build` flags and args to pass to marine build. Can be overridden using --marine-build-args flag Default: --release",
|
||||
"nullable": true
|
||||
},
|
||||
"cliVersion": {
|
||||
"type": "string",
|
||||
"description": "The version of the Fluence CLI that is compatible with this project. Set this to enforce a particular set of versions of all fluence components",
|
||||
"nullable": true
|
||||
},
|
||||
"ipfsAddr": {
|
||||
"type": "string",
|
||||
"description": "IPFS multiaddress to use when uploading workers with 'deal deploy'. Default: /dns4/ipfs.fluence.dev/tcp/5001 or /ip4/127.0.0.1/tcp/5001 if using local local env (for 'workers deploy' IPFS address provided by relay that you are connected to is used)",
|
||||
"nullable": true,
|
||||
"default": "/dns4/ipfs.fluence.dev/tcp/5001"
|
||||
},
|
||||
"customFluenceEnv": {
|
||||
"type": "object",
|
||||
"description": "Custom Fluence environment to use when connecting to Fluence network",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"contractsEnv": {
|
||||
"type": "string",
|
||||
"description": "Contracts environment to use for this fluence network to sign contracts on the blockchain",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"relays": {
|
||||
"type": "array",
|
||||
"description": "List of custom relay multiaddresses to use when connecting to Fluence network",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contractsEnv",
|
||||
"relays"
|
||||
]
|
||||
},
|
||||
"defaultSecretKeyName": {
|
||||
"description": "Secret key with this name will be used by default by js-client inside CLI to run Aqua code",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"relaysPath": {
|
||||
"description": "Path to the directory where you want relays.json file to be generated. Must be relative to the project root dir. This file contains a list of relays to use when connecting to Fluence network and depends on the default environment that you use in your project",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"$id": "https://fluence.dev/schemas/fluence.yaml",
|
||||
"title": "fluence.yaml",
|
||||
"description": "Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project"
|
||||
}
|
@ -2,14 +2,28 @@
|
||||
|
||||
This is a minimalistic Node.js application for Fluence using Fluence JS Client.
|
||||
|
||||
> To run this example you need `@latest` version of Fluence CLI. You can find installation guide [here](https://github.com/fluencelabs/cli).
|
||||
|
||||
## Getting started
|
||||
|
||||
Go to `src/frontend` folder:
|
||||
|
||||
```bash
|
||||
cd ./src/frontend
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
```
|
||||
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
Run the Node.js application:
|
||||
|
||||
```bash
|
||||
|
13
js-client-examples/hello-world/fluence.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
40328
js-client-examples/hello-world/package-lock.json
generated
@ -4,8 +4,9 @@ service HelloWorld("hello-world"):
|
||||
hello(str: string)
|
||||
getFortune() -> string
|
||||
|
||||
func sayHello():
|
||||
func sayHello() -> string:
|
||||
HelloWorld.hello("Hello, world!")
|
||||
<- "OK"
|
||||
|
||||
func tellFortune() -> string:
|
||||
res <- HelloWorld.getFortune()
|
@ -27,4 +27,4 @@ yarn-error.log*
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
src/compiled-aqua/*
|
9743
js-client-examples/hello-world/src/frontend/package-lock.json
generated
Normal file
@ -5,19 +5,13 @@
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "node --loader ts-node/esm ./src/index.ts",
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/cli": "0.9.1",
|
||||
"@fluencelabs/aqua-lib": "0.7.7",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "^4.6.3",
|
||||
"@types/jest": "29.4.0",
|
||||
@ -25,8 +19,6 @@
|
||||
"ts-jest": "29.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client.api": "0.13.1",
|
||||
"@fluencelabs/js-client.node": "0.7.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.1.2"
|
||||
"@fluencelabs/js-client": "^0.5.4"
|
||||
}
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
import '@fluencelabs/js-client.node';
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import { randomKras } from '@fluencelabs/fluence-network-environment';
|
||||
import { registerHelloWorld, sayHello, getRelayTime, tellFortune } from './_aqua/hello-world.js';
|
||||
import { Fluence } from '@fluencelabs/js-client';
|
||||
import relays from './relays.json' assert { type: "json" };
|
||||
import { registerHelloWorld, sayHello, getRelayTime, tellFortune } from './compiled-aqua/hello-world.js';
|
||||
|
||||
export async function main() {
|
||||
await Fluence.connect(randomKras());
|
||||
await Fluence.connect(relays[0]);
|
||||
|
||||
registerHelloWorld({
|
||||
hello: (str) => {
|
46
js-client-examples/hello-world/src/frontend/src/relays.json
Normal file
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"multiaddr": "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e",
|
||||
"peerId": "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51",
|
||||
"peerId": "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"peerId": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"peerId": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
"peerId": "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
"peerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
"peerId": "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"peerId": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn",
|
||||
"peerId": "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"peerId": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm",
|
||||
"peerId": "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm"
|
||||
}
|
||||
]
|
@ -11,7 +11,8 @@
|
||||
"declaration": true,
|
||||
"declarationMap": false,
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "nodenext"
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"include": ["src"]
|
12
js-client-examples/marine-service/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
.idea
|
||||
.DS_Store
|
||||
/.fluence/secrets
|
||||
/.fluence/env.yaml
|
||||
/.fluence/schemas
|
||||
/.fluence/tmp
|
||||
**/node_modules
|
||||
**/target/
|
||||
.repl_history
|
||||
/.vscode/settings.json
|
||||
/src/ts/src/aqua
|
||||
/src/js/src/aqua
|
2
js-client-examples/marine-service/Cargo.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[workspace]
|
||||
members = [ "src/services/myService/modules/myService" ]
|
39
js-client-examples/marine-service/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Getting Started with Fluence
|
||||
|
||||
This example demonstrates how to use marine services via JS client. It will work both in frontend and backend environments. The wasm file from the example has been taken from [this](https://github.com/fluencelabs/examples/tree/main/marine-examples/greeting) example.
|
||||
|
||||
> To learn how to build marine services, peek at `marine-examples` folder in this repository or in Marine [docs](https://fluence.dev/docs/marine-book/introduction).
|
||||
|
||||
> To run this example you need `@latest` version of Fluence CLI. You can find installation guide [here](https://github.com/fluencelabs/cli).
|
||||
|
||||
## Getting started
|
||||
|
||||
Go to `src/frontend` folder:
|
||||
|
||||
```bash
|
||||
cd ./src/frontend
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
```
|
||||
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
Start the dev server
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Click on the link in console output. Window on `localhost:5173` should open. After that wait for the button and click it. You should see "Hi, Fluence".
|
||||
|
||||
## Learn more
|
||||
|
||||
To learn more, refer to the [documentation page](https://fluence.dev//docs/build/js-client/js-client)
|
13
js-client-examples/marine-service/fluence.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua/greeting.aqua
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
14
js-client-examples/marine-service/src/aqua/greeting.aqua
Normal file
@ -0,0 +1,14 @@
|
||||
import Srv from "./srv.aqua"
|
||||
|
||||
export hello as my_hello
|
||||
|
||||
service Greeting:
|
||||
greeting(name: string) -> string
|
||||
|
||||
service Debug("debug"):
|
||||
stringify(message: string)
|
||||
|
||||
func hello(name: string, wasm_content: string) -> string:
|
||||
created_service <- Srv.create(wasm_content)
|
||||
Greeting created_service.service_id!
|
||||
<- Greeting.greeting(name)
|
25
js-client-examples/marine-service/src/aqua/srv.aqua
Normal file
@ -0,0 +1,25 @@
|
||||
data ServiceCreationResult:
|
||||
success: bool
|
||||
service_id: ?string
|
||||
error: ?string
|
||||
|
||||
data RemoveResult:
|
||||
success: bool
|
||||
error: ?string
|
||||
|
||||
alias ListServiceResult: []string
|
||||
|
||||
service Srv("single_module_srv"):
|
||||
-- Used to create a service on a certain node
|
||||
-- Arguments:
|
||||
-- bytes – a base64 string containing the .wasm module to add.
|
||||
-- Returns: service_id – the service ID of the created service.
|
||||
create(wasm_b64_content: string) -> ServiceCreationResult
|
||||
|
||||
-- Used to remove a service from a certain node
|
||||
-- Arguments:
|
||||
-- service_id – ID of the service to remove
|
||||
remove(service_id: string) -> RemoveResult
|
||||
|
||||
-- Returns a list of services ids running on a peer
|
||||
list() -> ListServiceResult
|
16
js-client-examples/marine-service/src/frontend/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgc3R5bGU9ImZpbGw6bm9uZSI+PHBhdGggZD0iTTE3LjI3NyAwaC0yLjQzNHY1LjM1NGMtNS4zNy41NzctOS41NSA1LjEyMy05LjU1IDEwLjY0NiAwIDUuNTIzIDQuMTggMTAuMDcgOS41NSAxMC42NDZWMzJoMi40MzR2LTUuMzY4YzUuMzEtLjYzMiA5LjQzLTUuMTUgOS40My0xMC42MzIgMC01LjQ4MS00LjEyLTEwLTkuNDMtMTAuNjMyek03LjcyNiAxNmE4LjI3NiA4LjI3NiAwIDAgMSA3LjExOS04LjE5NHYxNi4zODhBOC4yNzYgOC4yNzYgMCAwIDEgNy43MjYgMTZabTE2LjU0OCAwYTguMjc2IDguMjc2IDAgMCAxLTYuOTk2IDguMTc2VjcuODI0QTguMjc2IDguMjc2IDAgMCAxIDI0LjI3MyAxNloiIHN0eWxlPSJjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNlNDFjNWM7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOmV2ZW5vZGQiLz48L3N2Zz4="
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Fluence</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="src/index.ts"></script>
|
||||
</body>
|
||||
</html>
|
3847
js-client-examples/marine-service/src/frontend/package-lock.json
generated
Normal file
19
js-client-examples/marine-service/src/frontend/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client": "0.5.4",
|
||||
"js-base64": "^3.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "5.0.2",
|
||||
"vite": "4.4.5",
|
||||
"vite-plugin-node-polyfills": "0.16.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
/**
|
||||
*
|
||||
* This file is generated using:
|
||||
* @fluencelabs/aqua-api version: 0.12.0
|
||||
* @fluencelabs/aqua-to-js version: 0.1.0
|
||||
* If you find any bugs in generated AIR, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||
* If you find any bugs in generated JS/TS, please write an issue on GitHub: https://github.com/fluencelabs/js-client/issues
|
||||
*
|
||||
*/
|
||||
import type { IFluenceClient as IFluenceClient$$, CallParams as CallParams$$ } from '@fluencelabs/js-client';
|
||||
|
||||
import {
|
||||
v5_callFunction as callFunction$$,
|
||||
v5_registerService as registerService$$,
|
||||
} from '@fluencelabs/js-client';
|
||||
|
||||
// Services
|
||||
export interface DebugDef {
|
||||
stringify: (message: string, callParams: CallParams$$<'message'>) => void | Promise<void>;
|
||||
}
|
||||
export function registerDebug(service: DebugDef): void;
|
||||
export function registerDebug(serviceId: string, service: DebugDef): void;
|
||||
export function registerDebug(peer: IFluenceClient$$, service: DebugDef): void;
|
||||
export function registerDebug(peer: IFluenceClient$$, serviceId: string, service: DebugDef): void;
|
||||
export function registerDebug(...args: any[]) {
|
||||
registerService$$(
|
||||
args,
|
||||
{
|
||||
"defaultServiceId": "debug",
|
||||
"functions": {
|
||||
"fields": {
|
||||
"stringify": {
|
||||
"domain": {
|
||||
"fields": {
|
||||
"message": {
|
||||
"name": "string",
|
||||
"tag": "scalar"
|
||||
}
|
||||
},
|
||||
"tag": "labeledProduct"
|
||||
},
|
||||
"codomain": {
|
||||
"tag": "nil"
|
||||
},
|
||||
"tag": "arrow"
|
||||
}
|
||||
},
|
||||
"tag": "labeledProduct"
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export interface GreetingDef {
|
||||
greeting: (name: string, callParams: CallParams$$<'name'>) => string | Promise<string>;
|
||||
}
|
||||
export function registerGreeting(service: GreetingDef): void;
|
||||
export function registerGreeting(serviceId: string, service: GreetingDef): void;
|
||||
export function registerGreeting(peer: IFluenceClient$$, service: GreetingDef): void;
|
||||
export function registerGreeting(peer: IFluenceClient$$, serviceId: string, service: GreetingDef): void;
|
||||
export function registerGreeting(...args: any[]) {
|
||||
registerService$$(
|
||||
args,
|
||||
{
|
||||
"functions": {
|
||||
"fields": {
|
||||
"greeting": {
|
||||
"domain": {
|
||||
"fields": {
|
||||
"name": {
|
||||
"name": "string",
|
||||
"tag": "scalar"
|
||||
}
|
||||
},
|
||||
"tag": "labeledProduct"
|
||||
},
|
||||
"codomain": {
|
||||
"items": [
|
||||
{
|
||||
"name": "string",
|
||||
"tag": "scalar"
|
||||
}
|
||||
],
|
||||
"tag": "unlabeledProduct"
|
||||
},
|
||||
"tag": "arrow"
|
||||
}
|
||||
},
|
||||
"tag": "labeledProduct"
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Functions
|
||||
export const my_hello_script = `
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||
(call %init_peer_id% ("getDataSrv" "name") [] -name-arg-)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "wasm_content") [] -wasm_content-arg-)
|
||||
)
|
||||
(call %init_peer_id% ("single_module_srv" "create") [-wasm_content-arg-] ret)
|
||||
)
|
||||
(call %init_peer_id% (ret.$.service_id.[0] "greeting") [-name-arg-] ret-0)
|
||||
)
|
||||
(call %init_peer_id% ("callbackSrv" "response") [ret-0])
|
||||
)
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [:error: 0])
|
||||
)
|
||||
`;
|
||||
|
||||
export function my_hello(
|
||||
name: string,
|
||||
wasm_content: string,
|
||||
config?: {ttl?: number}
|
||||
): Promise<string>;
|
||||
|
||||
export function my_hello(
|
||||
peer: IFluenceClient$$,
|
||||
name: string,
|
||||
wasm_content: string,
|
||||
config?: {ttl?: number}
|
||||
): Promise<string>;
|
||||
|
||||
export function my_hello(...args: any[]) {
|
||||
return callFunction$$(
|
||||
args,
|
||||
{
|
||||
"functionName": "my_hello",
|
||||
"arrow": {
|
||||
"domain": {
|
||||
"fields": {
|
||||
"name": {
|
||||
"name": "string",
|
||||
"tag": "scalar"
|
||||
},
|
||||
"wasm_content": {
|
||||
"name": "string",
|
||||
"tag": "scalar"
|
||||
}
|
||||
},
|
||||
"tag": "labeledProduct"
|
||||
},
|
||||
"codomain": {
|
||||
"items": [
|
||||
{
|
||||
"name": "string",
|
||||
"tag": "scalar"
|
||||
}
|
||||
],
|
||||
"tag": "unlabeledProduct"
|
||||
},
|
||||
"tag": "arrow"
|
||||
},
|
||||
"names": {
|
||||
"relay": "-relay-",
|
||||
"getDataSrv": "getDataSrv",
|
||||
"callbackSrv": "callbackSrv",
|
||||
"responseSrv": "callbackSrv",
|
||||
"responseFnName": "response",
|
||||
"errorHandlingSrv": "errorHandlingSrv",
|
||||
"errorFnName": "error"
|
||||
}
|
||||
},
|
||||
my_hello_script
|
||||
);
|
||||
}
|
86
js-client-examples/marine-service/src/frontend/src/index.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import { Fluence } from '@fluencelabs/js-client';
|
||||
import relays from './relays.json' assert { type: 'json' };
|
||||
import { my_hello } from './compiled-aqua/greeting.ts';
|
||||
import greetingWasmUrl from '../wasm/greeting.wasm?url';
|
||||
import { fromUint8Array } from 'js-base64';
|
||||
|
||||
const appEl =
|
||||
document.querySelector("#app") ??
|
||||
(() => {
|
||||
throw new Error("#app element is not found");
|
||||
})();
|
||||
|
||||
|
||||
|
||||
const aquaFunctions = [
|
||||
{
|
||||
name: "Greeting Service",
|
||||
async fn() {
|
||||
const greetingWasm = await fetch(greetingWasmUrl).then(res => res.arrayBuffer());
|
||||
const base64GreetingWasm = fromUint8Array(new Uint8Array(greetingWasm));
|
||||
return my_hello("Fluence", base64GreetingWasm);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
(async () => {
|
||||
const p = document.createElement("p");
|
||||
p.innerText = "Loading...";
|
||||
appEl.append(p);
|
||||
try {
|
||||
await Fluence.connect(relays[0].multiaddr);
|
||||
} catch (error) {
|
||||
p.style.color = "red";
|
||||
p.innerText = `❌ ${stringifyError(error)}`;
|
||||
throw error;
|
||||
}
|
||||
|
||||
p.remove();
|
||||
|
||||
aquaFunctions.forEach((aquaFn) => {
|
||||
const buttonEl = document.createElement("button");
|
||||
buttonEl.innerText = aquaFn.name;
|
||||
|
||||
buttonEl.addEventListener("click", () => {
|
||||
runAquaFunction(aquaFn);
|
||||
});
|
||||
|
||||
appEl.append(buttonEl);
|
||||
});
|
||||
})();
|
||||
|
||||
type AquaFunction = {
|
||||
name: string;
|
||||
fn: () => Promise<unknown>;
|
||||
};
|
||||
|
||||
async function runAquaFunction({ fn, name }: AquaFunction) {
|
||||
const p = document.createElement("p");
|
||||
p.style.whiteSpace = "pre-wrap";
|
||||
try {
|
||||
const res = await fn();
|
||||
p.style.color = "green";
|
||||
p.innerHTML = `${name}: ✅ ${JSON.stringify(res, null, 2)}`;
|
||||
} catch (e) {
|
||||
p.style.color = "red";
|
||||
p.innerHTML = `${name}: ❌ ${stringifyError(e)}`;
|
||||
}
|
||||
appEl.append(p);
|
||||
}
|
||||
|
||||
function stringifyError(e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
return e.message;
|
||||
}
|
||||
|
||||
if (e instanceof Object) {
|
||||
const message = JSON.stringify(e, null, 2);
|
||||
if (message.includes("[0].dealIdOriginal")) {
|
||||
return "Please, make sure you have deployed the service";
|
||||
}
|
||||
|
||||
return JSON.stringify(e, null, 2);
|
||||
}
|
||||
|
||||
return String(e);
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"multiaddr": "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e",
|
||||
"peerId": "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51",
|
||||
"peerId": "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"peerId": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"peerId": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
"peerId": "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
"peerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
"peerId": "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"peerId": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn",
|
||||
"peerId": "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"peerId": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm",
|
||||
"peerId": "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm"
|
||||
}
|
||||
]
|
24
js-client-examples/marine-service/src/frontend/tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"types": ["vite/client"],
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { nodePolyfills } from "vite-plugin-node-polyfills";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [nodePolyfills()],
|
||||
});
|
BIN
js-client-examples/marine-service/src/frontend/wasm/greeting.wasm
Executable file
779
js-client-examples/node-example/.fluence/schemas/fluence.json
Normal file
@ -0,0 +1,779 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "A map with service names as keys and Service configs as values. You can have any number of services listed here as long as service name keys start with a lowercase letter and contain only letters numbers and underscores. You can use `fluence service add` command to add a service to this config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Service_name": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 5
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"title": "Dependencies",
|
||||
"nullable": true,
|
||||
"description": "(For advanced users) Overrides for the project dependencies",
|
||||
"properties": {
|
||||
"npm": {
|
||||
"type": "object",
|
||||
"title": "npm dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of npm aqua dependency versions. Fluence CLI ensures dependencies are installed each time you run aqua",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"npm_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "npm dependency version"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"cargo": {
|
||||
"type": "object",
|
||||
"title": "Cargo dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of cargo dependency versions. Fluence CLI ensures dependencies are installed each time you run commands that depend on Marine or Marine REPL",
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Cargo_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "cargo dependency version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaInputPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the aqua file or directory with aqua files that you want to compile by default. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputTSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to ts. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputJSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to js. Must be relative to the project root dir. Overrides 'aquaOutputTSPath' property"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a list of peer IDs to host the worker on. Intended to be used by providers to deploy directly without using the blockchain",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"workerName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"deals": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a deal",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"dealName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"spells": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "A map with spell names as keys and spell configs as values",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Spell_name": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaImports": {
|
||||
"type": "array",
|
||||
"description": "A list of path to be considered by aqua compiler to be used as imports. First dependency in the list has the highest priority. Priority of imports is considered in the following order: imports from --import flags, imports from aquaImports property in fluence.yaml, project's .fluence/aqua dir, npm dependencies from fluence.yaml, npm dependencies from user's .fluence/config.yaml, npm dependencies recommended by fluence",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"marineBuildArgs": {
|
||||
"type": "string",
|
||||
"description": "Space separated `cargo build` flags and args to pass to marine build. Can be overridden using --marine-build-args flag Default: --release",
|
||||
"nullable": true
|
||||
},
|
||||
"cliVersion": {
|
||||
"type": "string",
|
||||
"description": "The version of the Fluence CLI that is compatible with this project. Set this to enforce a particular set of versions of all fluence components",
|
||||
"nullable": true
|
||||
},
|
||||
"ipfsAddr": {
|
||||
"type": "string",
|
||||
"description": "IPFS multiaddress to use when uploading workers with 'deal deploy'. Default: /dns4/ipfs.fluence.dev/tcp/5001 or /ip4/127.0.0.1/tcp/5001 if using local local env (for 'workers deploy' IPFS address provided by relay that you are connected to is used)",
|
||||
"nullable": true,
|
||||
"default": "/dns4/ipfs.fluence.dev/tcp/5001"
|
||||
},
|
||||
"customFluenceEnv": {
|
||||
"type": "object",
|
||||
"description": "Custom Fluence environment to use when connecting to Fluence network",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"contractsEnv": {
|
||||
"type": "string",
|
||||
"description": "Contracts environment to use for this fluence network to sign contracts on the blockchain",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"relays": {
|
||||
"type": "array",
|
||||
"description": "List of custom relay multiaddresses to use when connecting to Fluence network",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contractsEnv",
|
||||
"relays"
|
||||
]
|
||||
},
|
||||
"defaultSecretKeyName": {
|
||||
"description": "Secret key with this name will be used by default by js-client inside CLI to run Aqua code",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"relaysPath": {
|
||||
"description": "Path to the directory where you want relays.json file to be generated. Must be relative to the project root dir. This file contains a list of relays to use when connecting to Fluence network and depends on the default environment that you use in your project",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"$id": "https://fluence.dev/schemas/fluence.yaml",
|
||||
"title": "fluence.yaml",
|
||||
"description": "Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project"
|
||||
}
|
@ -2,14 +2,28 @@
|
||||
|
||||
This is a sample Node.js application using Fluence JS Client. It exposes a calculator service written in Typescript which can be accessed from Fluence Network using Aqua language
|
||||
|
||||
> To run this example you need `@latest` version of Fluence CLI. You can find installation guide [here](https://github.com/fluencelabs/cli).
|
||||
|
||||
## Getting started
|
||||
|
||||
Go to `src/frontend` folder:
|
||||
|
||||
```bash
|
||||
cd ./src/frontend
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
```
|
||||
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
Start the Node.js application:
|
||||
|
||||
```bash
|
||||
@ -18,10 +32,10 @@ npm start
|
||||
|
||||
This should start listening to incoming particles from Fluence Network.
|
||||
|
||||
Try interacting with the application with some aqua:
|
||||
Open another terminal window and go to the example dir. Try interacting with the application by executing aqua function:
|
||||
|
||||
```bash
|
||||
./run_calculation.sh
|
||||
fluence run -f 'demoCalculation()'
|
||||
```
|
||||
|
||||
## Learn more
|
||||
|
13
js-client-examples/node-example/fluence.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
40293
js-client-examples/node-example/package-lock.json
generated
@ -1,3 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
npx fluence run -i ./aqua/demo-calculation.aqua -f 'demoCalculation()'
|
@ -27,5 +27,5 @@ yarn-error.log*
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
src/compiled-aqua/*
|
||||
.fluence/
|
5120
js-client-examples/node-example/src/frontend/package-lock.json
generated
Normal file
@ -5,26 +5,20 @@
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "node --loader ts-node/esm ./src/index.ts",
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/cli": "0.9.1",
|
||||
"ts-node": "10.9.1",
|
||||
"@types/node": "20.8.10",
|
||||
"@types/jest": "29.4.0",
|
||||
"jest": "29.4.1",
|
||||
"ts-jest": "29.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client.api": "0.13.1",
|
||||
"@fluencelabs/js-client.node": "0.7.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.1.2"
|
||||
"@fluencelabs/js-client": "^0.5.4"
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { justStop, runServer } from '../main.js';
|
||||
import { demoCalculation } from '../_aqua/demo-calculation.js';
|
||||
import { demoCalculation } from '../compiled-aqua/demo-calculation.js';
|
||||
|
||||
describe('smoke test', () => {
|
||||
it('should work', async () => {
|
@ -1,7 +1,6 @@
|
||||
import '@fluencelabs/js-client.node';
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||
import { registerCalc, CalcDef } from './_aqua/calc.js';
|
||||
import { Fluence } from '@fluencelabs/js-client';
|
||||
import { registerCalc, CalcDef } from './compiled-aqua/calc.js';
|
||||
import relays from './relays.json' assert { type: "json" };
|
||||
|
||||
class Calc implements CalcDef {
|
||||
private _state: number = 0;
|
||||
@ -31,7 +30,7 @@ class Calc implements CalcDef {
|
||||
}
|
||||
}
|
||||
|
||||
const relay = kras[0];
|
||||
const relay = relays[0];
|
||||
|
||||
// generated with `npx aqua create_keypair`
|
||||
const skBase64 = 'tOpsT08fvYMnRypj3VtSoqWMN5W/AptKsP39yanlkg4=';
|
||||
@ -48,7 +47,7 @@ export async function runServer() {
|
||||
|
||||
registerCalc(new Calc());
|
||||
|
||||
const client = await Fluence.getClient();
|
||||
const client = Fluence.getClient();
|
||||
|
||||
console.log('application started');
|
||||
console.log('peer id is: ', client.getPeerId());
|
46
js-client-examples/node-example/src/frontend/src/relays.json
Normal file
@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"multiaddr": "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e",
|
||||
"peerId": "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51",
|
||||
"peerId": "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA",
|
||||
"peerId": "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf",
|
||||
"peerId": "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
"peerId": "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
"peerId": "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
"peerId": "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr",
|
||||
"peerId": "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn",
|
||||
"peerId": "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
"peerId": "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt"
|
||||
},
|
||||
{
|
||||
"multiaddr": "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm",
|
||||
"peerId": "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm"
|
||||
}
|
||||
]
|
@ -11,7 +11,8 @@
|
||||
"declaration": true,
|
||||
"declarationMap": false,
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "nodenext"
|
||||
"moduleResolution": "nodenext",
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"include": ["src"]
|
779
quickstart/1-browser-to-browser/.fluence/schemas/fluence.json
Normal file
@ -0,0 +1,779 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "A map with service names as keys and Service configs as values. You can have any number of services listed here as long as service name keys start with a lowercase letter and contain only letters numbers and underscores. You can use `fluence service add` command to add a service to this config",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Service_name": {
|
||||
"title": "Service config",
|
||||
"description": "Service config. Defines where the service is and how to deploy it",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to service directory or URL to the tar.gz archive with the service"
|
||||
},
|
||||
"overrideModules": {
|
||||
"type": "object",
|
||||
"title": "Overrides",
|
||||
"description": "A map of modules to override",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"properties": {
|
||||
"Module_name": {
|
||||
"type": "object",
|
||||
"title": "Module overrides",
|
||||
"description": "Overrides for the module config",
|
||||
"properties": {
|
||||
"maxHeapSize": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Max size of the heap that a module can allocate in format: [number][whitespace?][specificator?] where ? is an optional field and specificator is one from the following (case-insensitive):\nK, Kb - kilobyte\nKi, KiB - kibibyte\nM, Mb - megabyte\nMi, MiB - mebibyte\nG, Gb - gigabyte\nGi, GiB - gibibyte\nCurrent limit is 4 GiB"
|
||||
},
|
||||
"loggerEnabled": {
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "Set true to allow module to use the Marine SDK logger"
|
||||
},
|
||||
"loggingMask": {
|
||||
"type": "number",
|
||||
"nullable": true,
|
||||
"description": "manages the logging targets, described in detail: https://fluence.dev/docs/marine-book/marine-rust-sdk/developing/logging#using-target-map"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"title": "Volumes",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Alias": {
|
||||
"type": "string",
|
||||
"description": "path"
|
||||
}
|
||||
},
|
||||
"description": "A map of accessible files and their aliases. Aliases should be used in Marine module development because it's hard to know the full path to a file"
|
||||
},
|
||||
"envs": {
|
||||
"type": "object",
|
||||
"title": "Environment variables",
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Environment_variable_name": {
|
||||
"type": "string",
|
||||
"description": "Environment variable value"
|
||||
}
|
||||
},
|
||||
"description": "environment variables accessible by a particular module with standard Rust env API like this: std::env::var(IPFS_ADDR_ENV_NAME). Please note that Marine adds three additional environment variables. Module environment variables could be examined with repl"
|
||||
},
|
||||
"mountedBinaries": {
|
||||
"title": "Mounted binaries",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Mounted_binary_name": {
|
||||
"type": "string",
|
||||
"description": "Path to a mounted binary"
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": [],
|
||||
"description": "A map of binary executable files that module is allowed to call. Example: curl: /usr/bin/curl"
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"nullable": true,
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 5
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "object",
|
||||
"title": "Dependencies",
|
||||
"nullable": true,
|
||||
"description": "(For advanced users) Overrides for the project dependencies",
|
||||
"properties": {
|
||||
"npm": {
|
||||
"type": "object",
|
||||
"title": "npm dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of npm aqua dependency versions. Fluence CLI ensures dependencies are installed each time you run aqua",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"npm_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "npm dependency version"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"cargo": {
|
||||
"type": "object",
|
||||
"title": "Cargo dependencies",
|
||||
"nullable": true,
|
||||
"description": "A map of cargo dependency versions. Fluence CLI ensures dependencies are installed each time you run commands that depend on Marine or Marine REPL",
|
||||
"required": [],
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"properties": {
|
||||
"Cargo_dependency_name": {
|
||||
"type": "string",
|
||||
"description": "cargo dependency version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaInputPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the aqua file or directory with aqua files that you want to compile by default. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputTSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to ts. Must be relative to the project root dir"
|
||||
},
|
||||
"aquaOutputJSPath": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Path to the default compilation target dir from aqua to js. Must be relative to the project root dir. Overrides 'aquaOutputTSPath' property"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a list of peer IDs to host the worker on. Intended to be used by providers to deploy directly without using the blockchain",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"workerName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"peerIds": {
|
||||
"type": "array",
|
||||
"description": "An array of peer IDs to deploy on",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"deals": {
|
||||
"description": "A map of objects with worker names as keys, each object defines a deal",
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"properties": {
|
||||
"dealName": {
|
||||
"type": "object",
|
||||
"description": "Worker config",
|
||||
"properties": {
|
||||
"services": {
|
||||
"description": "An array of service names to include in this worker. Service names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"spells": {
|
||||
"description": "An array of spell names to include in this worker. Spell names must be listed in fluence.yaml",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"minWorkers": {
|
||||
"type": "number",
|
||||
"description": "Required workers to activate the deal",
|
||||
"default": 1,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
},
|
||||
"targetWorkers": {
|
||||
"type": "number",
|
||||
"description": "Max workers in the deal",
|
||||
"default": 3,
|
||||
"nullable": true,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"spells": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "A map with spell names as keys and spell configs as values",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"Spell_name": {
|
||||
"type": "object",
|
||||
"description": "Spell config",
|
||||
"properties": {
|
||||
"get": {
|
||||
"type": "string",
|
||||
"description": "Path to spell"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"const": 0
|
||||
},
|
||||
"aquaFilePath": {
|
||||
"type": "string",
|
||||
"description": "Path to Aqua file which contains an Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"function": {
|
||||
"type": "string",
|
||||
"description": "Name of the Aqua function that you want to use as a spell",
|
||||
"nullable": true
|
||||
},
|
||||
"initArgs": {
|
||||
"type": "object",
|
||||
"description": "A map of Aqua function arguments names as keys and arguments values as values. They will be passed to the spell function and will be stored in the key-value storage for this particular spell.",
|
||||
"nullable": true
|
||||
},
|
||||
"clock": {
|
||||
"type": "object",
|
||||
"nullable": true,
|
||||
"description": "Trigger the spell execution periodically. If you want to disable this property by overriding it in fluence.yaml - pass empty config for it like this: `clock: {}`",
|
||||
"properties": {
|
||||
"periodSec": {
|
||||
"type": "number",
|
||||
"description": "How often the spell will be executed. If set to 0, the spell will be executed only once. If this value not provided at all - the spell will never be executed",
|
||||
"minimum": 0,
|
||||
"maximum": 3153600000,
|
||||
"nullable": true
|
||||
},
|
||||
"startTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should start. If this property or `startDelaySec` not specified, periodic execution will start immediately. If it is set to 0 - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"endTimestamp": {
|
||||
"type": "string",
|
||||
"description": "An ISO timestamp when the periodic execution should end. If this property or `endDelaySec` not specified, periodic execution will never end. If it is in the past at the moment of spell creation on Rust peer - the spell will never be executed",
|
||||
"nullable": true
|
||||
},
|
||||
"startDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the first execution in seconds. If this property or `startTimestamp` not specified, periodic execution will start immediately. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. This property conflicts with `startTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
},
|
||||
"endDelaySec": {
|
||||
"type": "number",
|
||||
"description": "How long to wait before the last execution in seconds. If this property or `endTimestamp` not specified, periodic execution will never end. WARNING! Currently your computer's clock is used to determine a final timestamp that is sent to the server. If it is in the past at the moment of spell creation - the spell will never be executed. This property conflicts with `endTimestamp`. You can specify only one of them",
|
||||
"nullable": true,
|
||||
"minimum": 0,
|
||||
"maximum": 4294967295
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"aquaImports": {
|
||||
"type": "array",
|
||||
"description": "A list of path to be considered by aqua compiler to be used as imports. First dependency in the list has the highest priority. Priority of imports is considered in the following order: imports from --import flags, imports from aquaImports property in fluence.yaml, project's .fluence/aqua dir, npm dependencies from fluence.yaml, npm dependencies from user's .fluence/config.yaml, npm dependencies recommended by fluence",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"marineBuildArgs": {
|
||||
"type": "string",
|
||||
"description": "Space separated `cargo build` flags and args to pass to marine build. Can be overridden using --marine-build-args flag Default: --release",
|
||||
"nullable": true
|
||||
},
|
||||
"cliVersion": {
|
||||
"type": "string",
|
||||
"description": "The version of the Fluence CLI that is compatible with this project. Set this to enforce a particular set of versions of all fluence components",
|
||||
"nullable": true
|
||||
},
|
||||
"ipfsAddr": {
|
||||
"type": "string",
|
||||
"description": "IPFS multiaddress to use when uploading workers with 'deal deploy'. Default: /dns4/ipfs.fluence.dev/tcp/5001 or /ip4/127.0.0.1/tcp/5001 if using local local env (for 'workers deploy' IPFS address provided by relay that you are connected to is used)",
|
||||
"nullable": true,
|
||||
"default": "/dns4/ipfs.fluence.dev/tcp/5001"
|
||||
},
|
||||
"customFluenceEnv": {
|
||||
"type": "object",
|
||||
"description": "Custom Fluence environment to use when connecting to Fluence network",
|
||||
"nullable": true,
|
||||
"properties": {
|
||||
"contractsEnv": {
|
||||
"type": "string",
|
||||
"description": "Contracts environment to use for this fluence network to sign contracts on the blockchain",
|
||||
"enum": [
|
||||
"kras",
|
||||
"testnet",
|
||||
"stage",
|
||||
"local"
|
||||
]
|
||||
},
|
||||
"relays": {
|
||||
"type": "array",
|
||||
"description": "List of custom relay multiaddresses to use when connecting to Fluence network",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contractsEnv",
|
||||
"relays"
|
||||
]
|
||||
},
|
||||
"defaultSecretKeyName": {
|
||||
"description": "Secret key with this name will be used by default by js-client inside CLI to run Aqua code",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"relaysPath": {
|
||||
"description": "Path to the directory where you want relays.json file to be generated. Must be relative to the project root dir. This file contains a list of relays to use when connecting to Fluence network and depends on the default environment that you use in your project",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"$id": "https://fluence.dev/schemas/fluence.yaml",
|
||||
"title": "fluence.yaml",
|
||||
"description": "Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project"
|
||||
}
|
@ -1,10 +1,99 @@
|
||||
# Getting started
|
||||
# 1. Browser-to-Browser
|
||||
|
||||
The first example demonstrates how to communicate between two client peers, i.e. browsers, with local services. The project is based on a create-react-app template with slight modifications to integrate Fluence. The primary focus is the integration itself and React could be swapped with any framework of your choice.
|
||||
|
||||
Make sure you are in the `examples/quickstart/1-browser-to-browser/src/frontend` directory to install the dependencies:
|
||||
|
||||
```sh
|
||||
cd 1-browser-to-browser/src/frontend
|
||||
npm install
|
||||
```
|
||||
|
||||
Run aqua compiler:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
fluence aqua
|
||||
```
|
||||
|
||||
Run the app with `npm start` :
|
||||
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
||||
The browser window with `localhost:3000` should open
|
||||
Which opens a new tab in your browser at `http://localhost:3000`. The browser tab, representing the client peer, wants you to pick a relay node it, i.e., the browser client, can connect to and, of course, allows the peer to respond to the browser client. Select any one of the offered relays:
|
||||
|
||||
To learn more, refer to the [documentation page](https://fluence.dev//docs/build/quick-start/browser-to-browser/)
|
||||
![Relay Selection](./assets/Relay-Selection.png)
|
||||
|
||||
The client peer is now connected to the relay and ready for business:
|
||||
|
||||
![Connection confirmation to network](./assets/Connection-confirmation-to-network.png)
|
||||
|
||||
Let's follow the instructions, open another browser tab preferably in another browser, using `http://localhost:3000` , select any one of the relays and copying the ensuing peer id and relay peer id to the first client peer, i.e. the first browser tab, and click the `say hello` button:
|
||||
|
||||
![Peer-to-peer communication between two browser client peers](./assets/Peer-to-peer-communication-between-two-browser-client-peers.png)
|
||||
|
||||
Congratulations, you just sent messages between two browsers over the Fluence peer-to-peer network, which is pretty cool! Even cooler, however, is how we got here using Aqua, Fluence's distributed network and application composition language.
|
||||
|
||||
Navigate to the `aqua` directory and open the `aqua/getting-started.aqua` file in your IDE or terminal:
|
||||
|
||||
```aqua
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
-- The service runs inside browser
|
||||
service HelloPeer("HelloPeer"):
|
||||
hello(from: PeerId) -> string
|
||||
|
||||
func sayHello(targetPeerId: PeerId, targetRelayPeerId: PeerId) -> string:
|
||||
on targetPeerId via targetRelayPeerId:
|
||||
res <- HelloPeer.hello(INIT_PEER_ID)
|
||||
<- res
|
||||
```
|
||||
|
||||
And yes, fewer than ten lines (!) are required for a client peer, like our browser, to connect to the network and start composing the local `HelloPeer` service to send messages.
|
||||
|
||||
In broad strokes, the Aqua code breaks down as follows:
|
||||
|
||||
- Import the Aqua [standard library](https://github.com/fluencelabs/aqua-lib) into our application (1)
|
||||
- Create a service interface binding to the local service (see below) with the `HelloPeer` namespace and `hello` function (4-5)
|
||||
- Create the function `sayHello` that executes the `hello` call on the provided `targetPeerId` via the provided `targetRelayPeerId` and returns the result (7-10). Recall the copy and paste job you did earlier in the browser tab for the peer and relay id? That's where these parameters are interacted with.
|
||||
|
||||
Not only is Aqua rather succinct in allowing you to seamlessly program both network routes and distributed application workflows but also provides the ability to compile Aqua to Typescript stubs wrapping compiled Aqua, called AIR -- short for Aqua Intermediate Representation, into ready to use code blocks. Navigate to the `src/_aqua` directory and open the `aqua/getting-started.ts` file and poke around a bit.
|
||||
|
||||
Note that the `src/App.tsx` file relies on the generated `_aqua/getting-started.ts` file (line 7):
|
||||
|
||||
```typescript
|
||||
import React, { useEffect, useState } from "react";
|
||||
import logo from "./logo.svg";
|
||||
import "./App.scss";
|
||||
|
||||
import { Fluence, kras } from "@fluencelabs/js-client";
|
||||
import { sayHello, registerHelloPeer } from "./_aqua/getting-started";
|
||||
```
|
||||
|
||||
We wrote a little more than a handful of lines of code in Aqua and ended up with a deployment-ready code block that includes both the network routing and compute logic to facilitate browser-to-browser messaging over a peer-to-peer network.
|
||||
|
||||
The local (browser) service `HelloPeer` is also implemented in the `App.tsx` file:
|
||||
|
||||
```typescript
|
||||
const connect = async (relayPeerId: string) => {
|
||||
try {
|
||||
await Fluence.connect(relayPeerId);
|
||||
|
||||
// Register handler for this call in aqua:
|
||||
// HelloPeer.hello(%init_peer_id%)
|
||||
registerHelloPeer({
|
||||
hello: (from) => {
|
||||
setHelloMessage("Hello from: \n" + from);
|
||||
return "Hello back to you, \n" + from;
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.log("Client could not connect", err);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
To summarize, we ran an app that facilities messaging between two browsers over a peer-to-peer network. Aqua allowed us in just a few lines of code to program both the network topology and the application workflow in barely more than a handful of lines of code. Hint: You should be excited. For more information on Aqua, see the [Aqua Book](https://fluence.dev/docs/aqua-book/introduction).
|
||||
|
||||
To learn how to write and deploy your own WebAssembly modules refer to [this](https://fluence.dev/docs/build/get-started) doc.
|
||||
|
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 195 KiB |
BIN
quickstart/1-browser-to-browser/assets/Relay-Selection.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
quickstart/1-browser-to-browser/assets/getting-started.aqua.png
Normal file
After Width: | Height: | Size: 45 KiB |
13
quickstart/1-browser-to-browser/fluence.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# yaml-language-server: $schema=.fluence/schemas/fluence.json
|
||||
|
||||
# Defines Fluence Project, most importantly - what exactly you want to deploy and how. You can use `fluence init` command to generate a template for new Fluence project
|
||||
|
||||
# Documentation: https://github.com/fluencelabs/cli/tree/main/docs/configs/fluence.md
|
||||
|
||||
version: 5
|
||||
|
||||
aquaInputPath: src/aqua
|
||||
|
||||
relaysPath: src/frontend/src
|
||||
|
||||
aquaOutputTSPath: src/frontend/src/compiled-aqua
|
@ -24,7 +24,7 @@ yarn-error.log*
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
src/compiled-aqua/*
|
||||
|
||||
public/*.wasm
|
||||
public/runnerScript.*
|
@ -3,31 +3,17 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/js-client.api": "0.13.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.1.2",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@fluencelabs/js-client": "^0.5.4",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.6.3",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
@ -50,14 +36,21 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/cli": "0.9.1",
|
||||
"@fluencelabs/aqua-lib": "0.7.7",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^14.5.1",
|
||||
"@types/jest": "^29.5.6",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/node": "^20.8.9",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"@types/react": "^18.2.33",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/serve-handler": "^6.1.3",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"react-scripts": "^5.0.1",
|
||||
"sass": "^1.58.3",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
"ts-jest": "^28.0.8",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -2,12 +2,11 @@ import React, { useEffect, useState } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.scss';
|
||||
|
||||
import { Fluence } from '@fluencelabs/js-client.api';
|
||||
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||
import { sayHello, registerHelloPeer } from './_aqua/getting-started';
|
||||
import { Fluence, type ConnectionState } from '@fluencelabs/js-client';
|
||||
import { sayHello, registerHelloPeer } from './compiled-aqua/getting-started';
|
||||
import relays from './relays.json';
|
||||
|
||||
const relayNodes = [kras[4], kras[5], kras[6]];
|
||||
const relayNodes = [relays[0], relays[1], relays[2]];
|
||||
|
||||
function App() {
|
||||
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||
@ -18,23 +17,20 @@ function App() {
|
||||
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
Fluence.onConnectionStateChange((state) => {
|
||||
console.log('Connection state changed to: ', state);
|
||||
setConnectionState(state);
|
||||
if (connectionState === 'connected') {
|
||||
const client = Fluence.getClient();
|
||||
|
||||
if (state === 'connected') {
|
||||
Fluence.getClient().then((client) => {
|
||||
const peerId = client.getPeerId();
|
||||
const relayPeerId = client.getRelayPeerId();
|
||||
setPeerInfo({ peerId, relayPeerId });
|
||||
});
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
const peerId = client.getPeerId();
|
||||
const relayPeerId = client.getRelayPeerId();
|
||||
setPeerInfo({ peerId, relayPeerId });
|
||||
}
|
||||
}, [connectionState]);
|
||||
|
||||
const connect = async (relayPeerId: string) => {
|
||||
try {
|
||||
setConnectionState('connecting');
|
||||
await Fluence.connect(relayPeerId);
|
||||
setConnectionState('connected');
|
||||
|
||||
// Register handler for this call in aqua:
|
||||
// HelloPeer.hello(%init_peer_id%)
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |