Compare commits
9 Commits
cc9e3c0940
...
1cfb754d75
Author | SHA1 | Date |
---|---|---|
|
1cfb754d75 | 3 days ago |
|
1753b6d5fb | 3 days ago |
|
bf8bdd94b9 | 3 days ago |
|
1039c2694d | 4 days ago |
|
44d4fcac3e | 4 days ago |
|
0ed801ac55 | 4 days ago |
|
5e01e2dc19 | 4 days ago |
|
74ab93c0b2 | 4 days ago |
|
9e5b787c39 | 4 days ago |
@ -0,0 +1,7 @@ |
|||||||
|
# Package Managers |
||||||
|
package-lock.json |
||||||
|
pnpm-lock.yaml |
||||||
|
yarn.lock |
||||||
|
*.json |
||||||
|
.prettierrc |
||||||
|
src-tauri/gen |
@ -0,0 +1,18 @@ |
|||||||
|
{ |
||||||
|
"useTabs": false, |
||||||
|
"singleQuote": false, |
||||||
|
"trailingComma": "none", |
||||||
|
"printWidth": 100, |
||||||
|
"tabWidth": 4, |
||||||
|
"plugins": [ |
||||||
|
"prettier-plugin-svelte" |
||||||
|
], |
||||||
|
"overrides": [ |
||||||
|
{ |
||||||
|
"files": "*.svelte", |
||||||
|
"options": { |
||||||
|
"parser": "svelte" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -1,7 +1,148 @@ |
|||||||
# Tauri + Vanilla TS |
# NextGraph apps (Linux, MacOS, Windows, Android, iOS, web) |
||||||
|
|
||||||
This template should help get you started developing with Tauri in vanilla HTML, CSS and Typescript. |
All the apps are based on Svelte and share the same code. |
||||||
|
|
||||||
|
The native apps are using the Tauri framework with an embedded WebView to render the Svelte app. |
||||||
|
|
||||||
|
## Install |
||||||
|
|
||||||
|
``` |
||||||
|
npm install -g pnpm |
||||||
|
pnpm install |
||||||
|
pnpm install @tauri-apps/cli |
||||||
|
``` |
||||||
|
|
||||||
## Recommended IDE Setup |
## Recommended IDE Setup |
||||||
|
|
||||||
- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) |
[VS Codium](https://vscodium.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). |
||||||
|
|
||||||
|
## Web |
||||||
|
|
||||||
|
prerequisites: compile the local JS/WASM SDK |
||||||
|
|
||||||
|
``` |
||||||
|
pnpm libwasm |
||||||
|
``` |
||||||
|
|
||||||
|
#### Dev |
||||||
|
|
||||||
|
First time: |
||||||
|
|
||||||
|
``` |
||||||
|
pnpm buildfrontdev |
||||||
|
``` |
||||||
|
|
||||||
|
Then run your local front-end: |
||||||
|
|
||||||
|
``` |
||||||
|
pnpm webdev |
||||||
|
// then open http://localhost:1421/ |
||||||
|
``` |
||||||
|
|
||||||
|
#### Prod |
||||||
|
|
||||||
|
this will produce a single html file embedding all the resources. this is what ngd broker needs for production |
||||||
|
|
||||||
|
``` |
||||||
|
pnpm webbuild |
||||||
|
``` |
||||||
|
|
||||||
|
## Desktop |
||||||
|
|
||||||
|
``` |
||||||
|
cargo install tauri-cli --version "^2.0.0" --locked |
||||||
|
``` |
||||||
|
|
||||||
|
Install [all prerequisites](https://tauri.app/start/prerequisites/) for your dev platform. |
||||||
|
|
||||||
|
Add this line to your environment variables |
||||||
|
|
||||||
|
``` |
||||||
|
export RANLIB="$NDK_HOME/toolchains/llvm/prebuilt/$(ls -1 $NDK_HOME/toolchains/llvm/prebuilt/)/bin/llvm-ranlib" |
||||||
|
``` |
||||||
|
|
||||||
|
to run the dev env : |
||||||
|
|
||||||
|
``` |
||||||
|
## on macos |
||||||
|
cargo tauri dev --no-watch --target x86_64-apple-darwin |
||||||
|
## on linux |
||||||
|
cargo tauri dev --no-watch --target x86_64-unknown-linux-gnu |
||||||
|
## on win |
||||||
|
cargo tauri dev --no-watch --target x86_64-pc-windows-msvc |
||||||
|
``` |
||||||
|
|
||||||
|
to build the production app installer : |
||||||
|
|
||||||
|
### MacOs (10.14+) |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri build |
||||||
|
// the installer is then available in target/x86_64-apple-darwin/release/bundle/dmg/NextGraph_0.1.2_x64.dmg |
||||||
|
// or if you just want the app, it is at target/x86_64-apple-darwin/release/bundle/macos/NextGraph.app |
||||||
|
``` |
||||||
|
|
||||||
|
### Linux (Ubuntu 22.04) |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri build --target x86_64-unknown-linux-gnu |
||||||
|
``` |
||||||
|
|
||||||
|
### Windows (7+) |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri build --target x86_64-pc-windows-msvc |
||||||
|
``` |
||||||
|
|
||||||
|
### Android |
||||||
|
|
||||||
|
- [Install Android Studio](https://developer.android.com/studio) |
||||||
|
|
||||||
|
- add the rust targets for android |
||||||
|
|
||||||
|
``` |
||||||
|
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android |
||||||
|
``` |
||||||
|
|
||||||
|
- follow the steps for Android in the [Prerequisites guide of Tauri](https://tauri.app/start/prerequisites/#android) |
||||||
|
|
||||||
|
Before you can generate the APK, you will need to [configure Android Studio with your Signing keys.](https://tauri.app/distribute/sign/android/) |
||||||
|
|
||||||
|
to launch the dev app : |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri android dev |
||||||
|
``` |
||||||
|
|
||||||
|
to build the production app : |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri android build |
||||||
|
``` |
||||||
|
|
||||||
|
to debug the Svelte app, use Chrome : |
||||||
|
|
||||||
|
- [chrome://inspect/#devices](chrome://inspect/#devices) |
||||||
|
- install the [svelte extension](https://chrome.google.com/webstore/detail/svelte-devtools/ckolcbmkjpjmangdbmnkpjigpkddpogn) |
||||||
|
|
||||||
|
### iOS |
||||||
|
|
||||||
|
Disclaimer: iOS hasn't been tested yet, for lack of suitable dev env (latest MacOS version needed). |
||||||
|
|
||||||
|
First, make sure Xcode is properly installed. then : |
||||||
|
|
||||||
|
``` |
||||||
|
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim |
||||||
|
``` |
||||||
|
|
||||||
|
to launch the dev app : |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri ios dev |
||||||
|
``` |
||||||
|
|
||||||
|
to build the production app : |
||||||
|
|
||||||
|
``` |
||||||
|
cargo tauri ios build |
||||||
|
``` |
||||||
|
@ -1,43 +1,182 @@ |
|||||||
|
<!-- |
||||||
|
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers |
||||||
|
// All rights reserved. |
||||||
|
// Licensed under the Apache License, Version 2.0 |
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0> |
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, |
||||||
|
// at your option. All files in the project carrying such |
||||||
|
// notice may not be copied, modified, or distributed except |
||||||
|
// according to those terms. |
||||||
|
--> |
||||||
<!doctype html> |
<!doctype html> |
||||||
<html lang="en"> |
<html lang="en"> |
||||||
<head> |
<head> |
||||||
<meta charset="UTF-8" /> |
<meta charset="UTF-8" /> |
||||||
<link rel="stylesheet" href="/src/styles.css" /> |
<link |
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
rel="icon" |
||||||
<title>Tauri App</title> |
type="image/svg+xml" |
||||||
<script type="module" src="/src/main.ts" defer></script> |
href="data:image/svg+xml;base64, |
||||||
</head> |
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMjUg |
||||||
|
MjI1Ij48Y2lyY2xlIGN4PSIxMDkuODgxIiBjeT0iMTEyLjkwNSIgcj0iMTA2Ljk4IiBzdHlsZT0i |
||||||
|
ZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2U6IG5vbmU7IHN0cm9rZS13aWR0aDogMC4y |
||||||
|
NjgzNzU7Ij48L2NpcmNsZT48cGF0aCBkPSJNOTguMzQzIDE5MC4yNjFjLTE3Ljk0LTIuNzI3LTMz |
||||||
|
LjMzMS0xMC42ODMtNDUuNzM1LTIzLjYzOC0xNC4wMDYtMTQuNjI5LTIxLjQzLTMzLjIxLTIxLjQz |
||||||
|
LTUzLjYzNSAwLTEwLjIxOCAxLjctMTkuNDQ0IDUuMjIxLTI4LjMzMiA0LjI4Ny0xMC44MiAxMC4w |
||||||
|
MzgtMTkuMzkgMTguNTM1LTI3LjYyMiA0LjczLTQuNTgyIDYuNjA3LTYuMTA3IDExLjI4MS05LjE2 |
||||||
|
MyAxMS45LTcuNzggMjQuMTc0LTExLjg4IDM4LjA5Ni0xMi43MjUgMTkuODA1LTEuMjAxIDM5LjEx |
||||||
|
MiA1LjExMyA1NC42MDMgMTcuODYgMS41MDcgMS4yNCAyLjczIDIuMzU4IDIuNzE2IDIuNDg2LS4w |
||||||
|
MTMuMTI4LTMuODU4IDMuNjM1LTguNTQ0IDcuNzkzLTQuNjg2IDQuMTU3LTEwLjA0NyA4Ljk2Mi0x |
||||||
|
MS45MTQgMTAuNjc3LTEuODY2IDEuNzE1LTMuNTQgMy4xMTktMy43MjEgMy4xMTktLjE4MSAwLTEu |
||||||
|
NC0uNzQ2LTIuNzEtMS42NTYtNy41My01LjIzOS0xNS45OTQtNy44MjItMjUuNjI1LTcuODIyLTEy |
||||||
|
LjczMiAwLTIzLjI1IDQuMzM4LTMyLjE0NCAxMy4yNTctNi4zOTYgNi40MTQtMTAuNzA0IDE0LjU1 |
||||||
|
Ni0xMi41IDIzLjYyNC0uNjkxIDMuNDg4LS42OSAxMy41My4wMDIgMTcuMDA5IDMuNzA1IDE4LjYy |
||||||
|
NiAxOC4zMTggMzMuMTAyIDM2LjY0MiAzNi4yOTcgNC4xNjQuNzI2IDExLjk4LjcxMiAxNS45OS0u |
||||||
|
MDI4IDE0LjAzMi0yLjU5NCAyNS44Ni0xMS4zNjggMzIuMjY1LTIzLjkzNi43NzQtMS41MTkgMS4y |
||||||
|
Ni0yLjg4NSAxLjA4LTMuMDM2LS4xNzgtLjE1Mi02Ljg3NC0xLjE3OC0xNC44NzctMi4yODEtOS43 |
||||||
|
OC0xLjM0OC0xNC45MjQtMi4yMTQtMTUuNjg1LTIuNjQxLTEuNTItLjg1NC0yLjgzNi0yLjg4OC0y |
||||||
|
LjgzNi00LjM4NiAwLTEuMTczIDIuMDI3LTE1Ljg2OSAyLjQ5LTE4LjA2LjI5OC0xLjQwMSAyLjQy |
||||||
|
Ni0zLjQ5MyAzLjg0NC0zLjc3Ny42MjItLjEyNCA4LjgyNy44NTYgMTguMjggMi4xODQgOS40MzQg |
||||||
|
MS4zMjUgMTcuMjYzIDIuMjk0IDE3LjM5OSAyLjE1NC4xMzYtLjE0IDEuMTE4LTYuNTQ4IDIuMTgz |
||||||
|
LTE0LjI0IDEuMTA4LTggMi4yMDQtMTQuNjAyIDIuNTYyLTE1LjQyNi4zNDQtLjc5MyAxLjExLTEu |
||||||
|
ODUgMS43MDMtMi4zNDggMi4wNjMtMS43MzYgMy4xNDMtMS43ODUgMTIuMjA0LS41NTMgOS42MzYg |
||||||
|
MS4zMSAxMC43MDkgMS41NjIgMTIuMjggMi44ODUgMS42NDQgMS4zODMgMi4yNzQgMi44MSAyLjI2 |
||||||
|
IDUuMTIzLS4wMDcgMS4xMDItLjkyMiA4LjI5Ny0yLjAzMyAxNS45ODktMS4xMTIgNy42OTEtMS45 |
||||||
|
NzIgMTQuMDQtMS45MTIgMTQuMTA5LjA2MS4wNjggNy4xNjcgMS4xMTEgMTUuNzkyIDIuMzE4IDEx |
||||||
|
LjEwNSAxLjU1NCAxNi4wMDggMi4zODcgMTYuODAyIDIuODU2IDEuNTMuOTA0IDIuNDggMi42NDgg |
||||||
|
Mi40NSA0LjQ5OC0uMDQ2IDIuODQ0LTIuNDEzIDE4LjEyMy0yLjk3NSAxOS4yMS0uNjYyIDEuMjgt |
||||||
|
Mi42MDMgMi41NDgtMy45MjEgMi41NjItLjUyLjAwNS03Ljg3NS0uOTYtMTYuMzQ0LTIuMTQ0LTgu |
||||||
|
NDctMS4xODUtMTUuNDc2LTIuMDc3LTE1LjU3LTEuOTgzLS4wOTQuMDk0LTEuMTg4IDcuMzQxLTIu |
||||||
|
NDMxIDE2LjEwNi0xLjQ0IDEwLjE1My0yLjQ5OCAxNi40MzYtMi45MTYgMTcuMzE2LS43MjUgMS41 |
||||||
|
MjgtMi43NjIgMy4wNjMtNC41MzggMy40MTgtLjk1Ny4xOTEtMTAuOS0uOTI4LTEzLjU5OC0xLjUz |
||||||
|
LS41NDgtLjEyMy0xLjg5Mi42NzItNC41MSAyLjY2NS0xMS4yNjMgOC41NzYtMjQuMzQyIDEzLjkx |
||||||
|
LTM4LjM1NyAxNS42NDItNC40LjU0NC0xNS43MjcuNDMzLTE5Ljg1NC0uMTk1eiIgc3R5bGU9ImZp |
||||||
|
bGw6IHJnYig3MywgMTE0LCAxNjUpOyBmaWxsLW9wYWNpdHk6IDE7IHN0cm9rZTogcmdiKDczLCAx |
||||||
|
MTQsIDE2NSk7IHN0cm9rZS13aWR0aDogMC4zNzc5NzY7IHN0cm9rZS1vcGFjaXR5OiAxOyI+PC9w |
||||||
|
YXRoPjwvc3ZnPg==" |
||||||
|
/> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||||
|
<title>NextGraph</title> |
||||||
|
<meta property="og:title" content="NextGraph App - The New Internet Platform" /> |
||||||
|
<meta property="og:image" content="https://nextgraph.org/card.png"/> |
||||||
|
<meta name="twitter:image" content="https://nextgraph.org/card-twitter.png"/> |
||||||
|
<meta name="twitter:card" content="summary_large_image" /> |
||||||
|
<meta property="og:description" content="Decentralized, encrypted and local-first platform and framework, towards the better internet we all deserve! Features a social network, shared documents, productivity tools, an app store, and more! You can use NextGraph for free, and it works online and offline. With NextGraph you own your data and software, having your privacy respected, while enjoying high-quality apps for your daily use. Try it now! Developers can build new web3.0 local-first apps with our open source framework, based on open standards, with CRDTs, E2EE, Semantic Web, RDF, SPARQL, JSON, Markdown, Svelte, React, JavaScript, Rust, etc... ActivityPub and Solid compatible." /> |
||||||
|
<meta name="description" content="Decentralized, encrypted and local-first platform and framework, towards the better internet we all deserve! Features a social network, shared documents, productivity tools, an app store, and more! You can use NextGraph for free, and it works online and offline. With NextGraph you own your data and software, having your privacy respected, while enjoying high-quality apps for your daily use. Try it now! Developers can build new web3.0 local-first apps with our open source framework, based on open standards, with CRDTs, E2EE, Semantic Web, RDF, SPARQL, JSON, Markdown, Svelte, React, JavaScript, Rust, etc... ActivityPub and Solid compatible."> |
||||||
|
<link rel="stylesheet" href="/src/styles.css" /> |
||||||
|
<style> |
||||||
|
.splashing { |
||||||
|
height: 100vh; |
||||||
|
width:100%; |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.noshow { |
||||||
|
display: none !important; |
||||||
|
} |
||||||
|
.error-no-wasm-hidden { |
||||||
|
display:none; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
</head> |
||||||
|
|
||||||
<body> |
<body> |
||||||
<main class="container"> |
<div id="splash" class="splashing"> |
||||||
<h1>Welcome to Tauri 2</h1> |
<div style="flex-direction: column; justify-content: center; |
||||||
|
color:#4972a5;width:100%;text-align:left; |
||||||
|
width:300px; |
||||||
|
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;" |
||||||
|
> |
||||||
|
<svg |
||||||
|
style="width:100px;height:100px;margin: 0 auto 20px ;display:flex;" |
||||||
|
xmlns="http://www.w3.org/2000/svg" |
||||||
|
viewBox="0 0 225 225" |
||||||
|
> |
||||||
|
<g> |
||||||
|
<circle |
||||||
|
r="106.98013" |
||||||
|
cy="112.90476" |
||||||
|
cx="109.88096" |
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.268375" /> |
||||||
|
<path |
||||||
|
d="M 98.343352,190.26108 C 80.403778,187.53354 65.011938,179.57839 52.608228,166.62327 38.602093,151.99448 31.178059,133.41381 31.178059,112.98841 c 0,-10.21889 1.700058,-19.44396 5.221234,-28.332119 4.28678,-10.820699 10.037295,-19.39063 18.535095,-27.62263 4.72982,-4.58187 6.60687,-6.10643 11.28099,-9.16256 11.89869,-7.779841 24.173884,-11.879991 38.095802,-12.724761 19.80437,-1.2017 39.11165,5.11306 54.60284,17.858751 1.50718,1.24006 2.72951,2.35934 2.71628,2.48729 -0.0132,0.12795 -3.85821,3.63443 -8.54442,7.79217 -4.6862,4.157729 -10.04724,8.96276 -11.91342,10.677819 -1.86617,1.715071 -3.54094,3.11831 -3.7217,3.11831 -0.18075,0 -1.39985,-0.745188 -2.70911,-1.655969 -7.53011,-5.23834 -15.99428,-7.82188 -25.62597,-7.82188 -12.731628,0 -23.249192,4.3379 -32.143882,13.257541 -6.39594,6.413868 -10.70387,14.555268 -12.50018,23.623578 -0.69099,3.48832 -0.68968,13.53072 0.002,17.00893 3.70508,18.62577 18.31886,33.10194 36.642322,36.29729 4.16439,0.72621 11.98099,0.71223 15.98975,-0.0286 14.03187,-2.59311 25.86047,-11.36806 32.26533,-23.93578 0.77379,-1.51834 1.26018,-2.88461 1.08086,-3.03616 -0.17934,-0.15156 -6.87448,-1.1779 -14.87813,-2.28078 -9.7795,-1.34758 -14.92353,-2.21379 -15.68471,-2.64117 -1.52067,-0.85379 -2.83611,-2.88806 -2.83611,-4.3859 0,-1.1732 2.02687,-15.86876 2.49085,-18.05962 0.29676,-1.40127 2.42559,-3.4934 3.84317,-3.77691 0.62227,-0.12445 8.82712,0.85555 18.28065,2.18348 9.43343,1.32511 17.26269,2.29453 17.39833,2.15427 0.13566,-0.14026 1.11808,-6.54833 2.18313,-14.24014 1.10778,-8.000208 2.20407,-14.60184 2.56177,-15.426229 0.34392,-0.792599 1.11019,-1.849131 1.70287,-2.34782 2.06321,-1.736079 3.1433,-1.785011 12.20439,-0.55291 9.63637,1.310309 10.70873,1.56224 12.28077,2.88503 1.64359,1.382979 2.2732,2.810909 2.25906,5.123309 -0.007,1.10173 -0.92172,8.29645 -2.03332,15.98826 -1.11158,7.69182 -1.97159,14.04091 -1.91113,14.1091 0.0605,0.0682 7.16644,1.11143 15.79109,2.31832 11.10566,1.55407 16.00827,2.38757 16.80223,2.85657 1.53015,0.90389 2.48023,2.64785 2.45017,4.49756 -0.0462,2.84349 -2.41252,18.12279 -2.97521,19.21089 -0.66164,1.27949 -2.60244,2.54696 -3.92109,2.56074 -0.51973,0.005 -7.87449,-0.95937 -16.34391,-2.144 -8.46944,-1.18464 -15.47588,-2.077 -15.56986,-1.98301 -0.094,0.094 -1.18792,7.34163 -2.43097,16.10589 -1.44004,10.15311 -2.49792,16.43621 -2.91556,17.31631 -0.72531,1.52848 -2.76261,3.06291 -4.53817,3.41802 -0.95688,0.19138 -10.90014,-0.92798 -13.59859,-1.53084 -0.5471,-0.12223 -1.89146,0.67252 -4.50941,2.66588 -11.2627,8.57562 -24.34195,13.90917 -38.35741,15.64164 -4.40038,0.54395 -15.72658,0.43298 -19.853658,-0.19451 z" |
||||||
|
style="fill:#4972a5;fill-opacity:1;stroke:#4972a5;stroke-width:0.377976;stroke-opacity:1" /> |
||||||
|
</g> |
||||||
|
</svg> |
||||||
|
|
||||||
<div class="row"> |
<div class="noshow" style="text-align:center;" id="app-loading"> Loading ...</div> |
||||||
<a href="https://vite.dev" target="_blank"> |
|
||||||
<img src="/src/assets/vite.svg" class="logo vite" alt="Vite logo" /> |
|
||||||
</a> |
|
||||||
<a href="https://tauri.app" target="_blank"> |
|
||||||
<img |
|
||||||
src="/src/assets/tauri.svg" |
|
||||||
class="logo tauri" |
|
||||||
alt="Tauri logo" |
|
||||||
/> |
|
||||||
</a> |
|
||||||
<a href="https://www.typescriptlang.org/docs" target="_blank"> |
|
||||||
<img |
|
||||||
src="/src/assets/typescript.svg" |
|
||||||
class="logo typescript" |
|
||||||
alt="typescript logo" |
|
||||||
/> |
|
||||||
</a> |
|
||||||
</div> |
|
||||||
<p>Click on the Tauri logo to learn more about the framework</p> |
|
||||||
|
|
||||||
<form class="row" id="greet-form"> |
<div id="error-no-wasm" style="padding-left:15px;" class="error-no-wasm-hidden"> |
||||||
<input id="greet-input" placeholder="Enter a name..." /> |
Your browser is too old or is miss-configured. |
||||||
<button type="submit">Greet</button> |
Please try one of those options:<br/><br/> |
||||||
</form> |
- Upgrade to a newer version of this browser.<br/> |
||||||
<p id="greet-msg"></p> |
- Try with another browser software.<br/> |
||||||
</main> |
- <a href="https://nextgraph.org/download">install our native apps for |
||||||
</body> |
Linux, macOS, Windows desktops and laptops, |
||||||
|
and iOS, Android mobiles.</a><br/><br/> |
||||||
|
If you are using jshelter or another javascript protection mechanism, |
||||||
|
please deactivate it as we need access to the WebWorker, JIT and WASM |
||||||
|
features of your browser. If those features are disabled, please |
||||||
|
enable them for this website. |
||||||
|
</div> |
||||||
|
<noscript style="display:grid;padding-left:15px;"> |
||||||
|
NextGraph cannot load as Javascript is currently deactivated. |
||||||
|
You can use the CLI ngcli to access your documents in the terminal. |
||||||
|
Or use the <a href="https://nextgraph.org/download">native apps |
||||||
|
for Linux, macOS, Windows, Android, iOS.</a><br/> |
||||||
|
Or setup an SSR static website generator with AtomicServer for javascript-less and |
||||||
|
read-only access. |
||||||
|
</noscript> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<script> |
||||||
|
const supported = () => { |
||||||
|
if (RegExp().hasIndices === undefined) { |
||||||
|
console.error("no RegExp().hasIndices"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
try { |
||||||
|
if (Worker === undefined) { |
||||||
|
console.error("no Worker"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
new Worker(URL.createObjectURL(new Blob([';'], {type: 'application/javascript'}))); |
||||||
|
if (typeof WebAssembly === "object" |
||||||
|
&& typeof WebAssembly.instantiate === "function") { |
||||||
|
const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00)); |
||||||
|
if (module instanceof WebAssembly.Module) |
||||||
|
return new WebAssembly.Instance(module) instanceof WebAssembly.Instance; |
||||||
|
else { |
||||||
|
console.log("no WebAssembly module"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} catch (e) { |
||||||
|
console.error(e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
console.error("no WebAssembly"); |
||||||
|
return false; |
||||||
|
}; |
||||||
|
if (check_supported && !supported()) { |
||||||
|
window.document.getElementById("error-no-wasm").className=""; |
||||||
|
} else { |
||||||
|
window.document.getElementById("app-loading").className=""; |
||||||
|
window.everything_ready = () => { |
||||||
|
window.document.getElementById("splash").className="noshow"; |
||||||
|
window.document.getElementById("app").className=""; |
||||||
|
}; |
||||||
|
window.onload = () => { |
||||||
|
window.ng_supported = true; |
||||||
|
console.log("window loaded"); |
||||||
|
if (window.ng_spa_loaded) { |
||||||
|
everything_ready(); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
</script> |
||||||
|
<div id="app" class="noshow"></div> |
||||||
|
<!-- # INSERT SCRIPT HERE --> |
||||||
|
</body> |
||||||
</html> |
</html> |
||||||
|
@ -0,0 +1,327 @@ |
|||||||
|
{ |
||||||
|
"name": "nextgraph", |
||||||
|
"version": "0.1.0", |
||||||
|
"lockfileVersion": 3, |
||||||
|
"requires": true, |
||||||
|
"packages": { |
||||||
|
"": { |
||||||
|
"name": "nextgraph", |
||||||
|
"version": "0.1.0", |
||||||
|
"dependencies": { |
||||||
|
"@tailwindcss/vite": "^4.1.14", |
||||||
|
"@tauri-apps/api": "^2", |
||||||
|
"@tauri-apps/plugin-opener": "^2" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@tauri-apps/cli": "^2.8.4", |
||||||
|
"tailwindcss": "^4.1.14", |
||||||
|
"typescript": "~5.6.2", |
||||||
|
"vite": "^7.1.7" |
||||||
|
} |
||||||
|
}, |
||||||
|
"../../node_modules/.pnpm/@tailwindcss+vite@4.1.14_vite@7.1.10_@types+node@24.3.0_jiti@2.6.1_lightningcss@1.30.1_yaml@2.8.1_/node_modules/@tailwindcss/vite": { |
||||||
|
"version": "4.1.14", |
||||||
|
"license": "MIT", |
||||||
|
"dependencies": { |
||||||
|
"@tailwindcss/node": "4.1.14", |
||||||
|
"@tailwindcss/oxide": "4.1.14", |
||||||
|
"tailwindcss": "4.1.14" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@types/node": "^20.19.0", |
||||||
|
"vite": "^7.0.0" |
||||||
|
}, |
||||||
|
"peerDependencies": { |
||||||
|
"vite": "^5.2.0 || ^6 || ^7" |
||||||
|
} |
||||||
|
}, |
||||||
|
"../../node_modules/.pnpm/@tauri-apps+api@2.8.0/node_modules/@tauri-apps/api": { |
||||||
|
"version": "2.8.0", |
||||||
|
"license": "Apache-2.0 OR MIT", |
||||||
|
"devDependencies": { |
||||||
|
"@eslint/js": "^9.29.0", |
||||||
|
"@rollup/plugin-terser": "0.4.4", |
||||||
|
"@rollup/plugin-typescript": "12.1.4", |
||||||
|
"@types/eslint": "^9.6.1", |
||||||
|
"@types/node": "^22.15.32", |
||||||
|
"eslint": "^9.29.0", |
||||||
|
"eslint-config-prettier": "10.1.8", |
||||||
|
"eslint-plugin-security": "3.0.1", |
||||||
|
"fast-glob": "3.3.3", |
||||||
|
"globals": "^16.2.0", |
||||||
|
"rollup": "4.46.3", |
||||||
|
"tslib": "^2.8.1", |
||||||
|
"typescript": "^5.8.3", |
||||||
|
"typescript-eslint": "^8.34.1" |
||||||
|
}, |
||||||
|
"funding": { |
||||||
|
"type": "opencollective", |
||||||
|
"url": "https://opencollective.com/tauri" |
||||||
|
} |
||||||
|
}, |
||||||
|
"../../node_modules/.pnpm/@tauri-apps+cli@2.8.4/node_modules/@tauri-apps/cli": { |
||||||
|
"version": "2.8.4", |
||||||
|
"dev": true, |
||||||
|
"license": "Apache-2.0 OR MIT", |
||||||
|
"bin": { |
||||||
|
"tauri": "tauri.js" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@napi-rs/cli": "^3.0.0", |
||||||
|
"@types/node": "^22.15.32", |
||||||
|
"cross-env": "10.0.0", |
||||||
|
"vitest": "^3.2.4" |
||||||
|
}, |
||||||
|
"engines": { |
||||||
|
"node": ">= 10" |
||||||
|
}, |
||||||
|
"funding": { |
||||||
|
"type": "opencollective", |
||||||
|
"url": "https://opencollective.com/tauri" |
||||||
|
}, |
||||||
|
"optionalDependencies": { |
||||||
|
"@tauri-apps/cli-darwin-arm64": "2.8.4", |
||||||
|
"@tauri-apps/cli-darwin-x64": "2.8.4", |
||||||
|
"@tauri-apps/cli-linux-arm-gnueabihf": "2.8.4", |
||||||
|
"@tauri-apps/cli-linux-arm64-gnu": "2.8.4", |
||||||
|
"@tauri-apps/cli-linux-arm64-musl": "2.8.4", |
||||||
|
"@tauri-apps/cli-linux-riscv64-gnu": "2.8.4", |
||||||
|
"@tauri-apps/cli-linux-x64-gnu": "2.8.4", |
||||||
|
"@tauri-apps/cli-linux-x64-musl": "2.8.4", |
||||||
|
"@tauri-apps/cli-win32-arm64-msvc": "2.8.4", |
||||||
|
"@tauri-apps/cli-win32-ia32-msvc": "2.8.4", |
||||||
|
"@tauri-apps/cli-win32-x64-msvc": "2.8.4" |
||||||
|
} |
||||||
|
}, |
||||||
|
"../../node_modules/.pnpm/@tauri-apps+plugin-opener@2.5.0/node_modules/@tauri-apps/plugin-opener": { |
||||||
|
"version": "2.5.0", |
||||||
|
"license": "MIT OR Apache-2.0", |
||||||
|
"dependencies": { |
||||||
|
"@tauri-apps/api": "^2.8.0" |
||||||
|
} |
||||||
|
}, |
||||||
|
"../../node_modules/.pnpm/typescript@5.6.3/node_modules/typescript": { |
||||||
|
"version": "5.6.3", |
||||||
|
"dev": true, |
||||||
|
"license": "Apache-2.0", |
||||||
|
"bin": { |
||||||
|
"tsc": "bin/tsc", |
||||||
|
"tsserver": "bin/tsserver" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@dprint/formatter": "^0.4.1", |
||||||
|
"@dprint/typescript": "0.91.6", |
||||||
|
"@esfx/canceltoken": "^1.0.0", |
||||||
|
"@eslint/js": "^9.9.0", |
||||||
|
"@octokit/rest": "^21.0.1", |
||||||
|
"@types/chai": "^4.3.17", |
||||||
|
"@types/diff": "^5.2.1", |
||||||
|
"@types/minimist": "^1.2.5", |
||||||
|
"@types/mocha": "^10.0.7", |
||||||
|
"@types/ms": "^0.7.34", |
||||||
|
"@types/node": "latest", |
||||||
|
"@types/source-map-support": "^0.5.10", |
||||||
|
"@types/which": "^3.0.4", |
||||||
|
"@typescript-eslint/rule-tester": "^8.1.0", |
||||||
|
"@typescript-eslint/type-utils": "^8.1.0", |
||||||
|
"@typescript-eslint/utils": "^8.1.0", |
||||||
|
"azure-devops-node-api": "^14.0.2", |
||||||
|
"c8": "^10.1.2", |
||||||
|
"chai": "^4.5.0", |
||||||
|
"chalk": "^4.1.2", |
||||||
|
"chokidar": "^3.6.0", |
||||||
|
"diff": "^5.2.0", |
||||||
|
"dprint": "^0.47.2", |
||||||
|
"esbuild": "^0.23.0", |
||||||
|
"eslint": "^9.9.0", |
||||||
|
"eslint-formatter-autolinkable-stylish": "^1.4.0", |
||||||
|
"eslint-plugin-regexp": "^2.6.0", |
||||||
|
"fast-xml-parser": "^4.4.1", |
||||||
|
"glob": "^10.4.5", |
||||||
|
"globals": "^15.9.0", |
||||||
|
"hereby": "^1.9.0", |
||||||
|
"jsonc-parser": "^3.3.1", |
||||||
|
"knip": "^5.27.2", |
||||||
|
"minimist": "^1.2.8", |
||||||
|
"mocha": "^10.7.3", |
||||||
|
"mocha-fivemat-progress-reporter": "^0.1.0", |
||||||
|
"monocart-coverage-reports": "^2.10.2", |
||||||
|
"ms": "^2.1.3", |
||||||
|
"node-fetch": "^3.3.2", |
||||||
|
"playwright": "^1.46.0", |
||||||
|
"source-map-support": "^0.5.21", |
||||||
|
"tslib": "^2.6.3", |
||||||
|
"typescript": "^5.5.4", |
||||||
|
"typescript-eslint": "^8.1.0", |
||||||
|
"which": "^3.0.1" |
||||||
|
}, |
||||||
|
"engines": { |
||||||
|
"node": ">=14.17" |
||||||
|
} |
||||||
|
}, |
||||||
|
"../../node_modules/.pnpm/vite@7.1.10_@types+node@24.3.0_jiti@2.6.1_lightningcss@1.30.1_yaml@2.8.1/node_modules/vite": { |
||||||
|
"version": "7.1.10", |
||||||
|
"dev": true, |
||||||
|
"license": "MIT", |
||||||
|
"dependencies": { |
||||||
|
"esbuild": "^0.25.0", |
||||||
|
"fdir": "^6.5.0", |
||||||
|
"picomatch": "^4.0.3", |
||||||
|
"postcss": "^8.5.6", |
||||||
|
"rollup": "^4.43.0", |
||||||
|
"tinyglobby": "^0.2.15" |
||||||
|
}, |
||||||
|
"bin": { |
||||||
|
"vite": "bin/vite.js" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@babel/parser": "^7.28.4", |
||||||
|
"@jridgewell/remapping": "^2.3.5", |
||||||
|
"@jridgewell/trace-mapping": "^0.3.31", |
||||||
|
"@oxc-project/types": "0.90.0", |
||||||
|
"@polka/compression": "^1.0.0-next.25", |
||||||
|
"@rolldown/pluginutils": "^1.0.0-beta.43", |
||||||
|
"@rollup/plugin-alias": "^5.1.1", |
||||||
|
"@rollup/plugin-commonjs": "^28.0.6", |
||||||
|
"@rollup/plugin-dynamic-import-vars": "2.1.4", |
||||||
|
"@rollup/pluginutils": "^5.3.0", |
||||||
|
"@types/escape-html": "^1.0.4", |
||||||
|
"@types/pnpapi": "^0.0.5", |
||||||
|
"artichokie": "^0.4.2", |
||||||
|
"baseline-browser-mapping": "^2.8.16", |
||||||
|
"cac": "^6.7.14", |
||||||
|
"chokidar": "^3.6.0", |
||||||
|
"connect": "^3.7.0", |
||||||
|
"convert-source-map": "^2.0.0", |
||||||
|
"cors": "^2.8.5", |
||||||
|
"cross-spawn": "^7.0.6", |
||||||
|
"debug": "^4.4.3", |
||||||
|
"dep-types": "link:./src/types", |
||||||
|
"dotenv": "^17.2.3", |
||||||
|
"dotenv-expand": "^12.0.3", |
||||||
|
"es-module-lexer": "^1.7.0", |
||||||
|
"escape-html": "^1.0.3", |
||||||
|
"estree-walker": "^3.0.3", |
||||||
|
"etag": "^1.8.1", |
||||||
|
"host-validation-middleware": "^0.1.2", |
||||||
|
"http-proxy-3": "^1.22.0", |
||||||
|
"launch-editor-middleware": "^2.11.1", |
||||||
|
"lightningcss": "^1.30.2", |
||||||
|
"magic-string": "^0.30.19", |
||||||
|
"mlly": "^1.8.0", |
||||||
|
"mrmime": "^2.0.1", |
||||||
|
"nanoid": "^5.1.6", |
||||||
|
"open": "^10.2.0", |
||||||
|
"parse5": "^8.0.0", |
||||||
|
"pathe": "^2.0.3", |
||||||
|
"periscopic": "^4.0.2", |
||||||
|
"picocolors": "^1.1.1", |
||||||
|
"postcss-import": "^16.1.1", |
||||||
|
"postcss-load-config": "^6.0.1", |
||||||
|
"postcss-modules": "^6.0.1", |
||||||
|
"premove": "^4.0.0", |
||||||
|
"resolve.exports": "^2.0.3", |
||||||
|
"rolldown": "^1.0.0-beta.43", |
||||||
|
"rolldown-plugin-dts": "^0.16.11", |
||||||
|
"rollup-plugin-license": "^3.6.0", |
||||||
|
"sass": "^1.93.2", |
||||||
|
"sass-embedded": "^1.93.2", |
||||||
|
"sirv": "^3.0.2", |
||||||
|
"strip-literal": "^3.1.0", |
||||||
|
"terser": "^5.44.0", |
||||||
|
"tsconfck": "^3.1.6", |
||||||
|
"types": "link:./types", |
||||||
|
"ufo": "^1.6.1", |
||||||
|
"ws": "^8.18.3" |
||||||
|
}, |
||||||
|
"engines": { |
||||||
|
"node": "^20.19.0 || >=22.12.0" |
||||||
|
}, |
||||||
|
"funding": { |
||||||
|
"url": "https://github.com/vitejs/vite?sponsor=1" |
||||||
|
}, |
||||||
|
"optionalDependencies": { |
||||||
|
"fsevents": "~2.3.3" |
||||||
|
}, |
||||||
|
"peerDependencies": { |
||||||
|
"@types/node": "^20.19.0 || >=22.12.0", |
||||||
|
"jiti": ">=1.21.0", |
||||||
|
"less": "^4.0.0", |
||||||
|
"lightningcss": "^1.21.0", |
||||||
|
"sass": "^1.70.0", |
||||||
|
"sass-embedded": "^1.70.0", |
||||||
|
"stylus": ">=0.54.8", |
||||||
|
"sugarss": "^5.0.0", |
||||||
|
"terser": "^5.16.0", |
||||||
|
"tsx": "^4.8.1", |
||||||
|
"yaml": "^2.4.2" |
||||||
|
}, |
||||||
|
"peerDependenciesMeta": { |
||||||
|
"@types/node": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"jiti": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"less": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"lightningcss": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"sass": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"sass-embedded": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"stylus": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"sugarss": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"terser": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"tsx": { |
||||||
|
"optional": true |
||||||
|
}, |
||||||
|
"yaml": { |
||||||
|
"optional": true |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"node_modules/@tailwindcss/vite": { |
||||||
|
"resolved": "../../node_modules/.pnpm/@tailwindcss+vite@4.1.14_vite@7.1.10_@types+node@24.3.0_jiti@2.6.1_lightningcss@1.30.1_yaml@2.8.1_/node_modules/@tailwindcss/vite", |
||||||
|
"link": true |
||||||
|
}, |
||||||
|
"node_modules/@tauri-apps/api": { |
||||||
|
"resolved": "../../node_modules/.pnpm/@tauri-apps+api@2.8.0/node_modules/@tauri-apps/api", |
||||||
|
"link": true |
||||||
|
}, |
||||||
|
"node_modules/@tauri-apps/cli": { |
||||||
|
"resolved": "../../node_modules/.pnpm/@tauri-apps+cli@2.8.4/node_modules/@tauri-apps/cli", |
||||||
|
"link": true |
||||||
|
}, |
||||||
|
"node_modules/@tauri-apps/plugin-opener": { |
||||||
|
"resolved": "../../node_modules/.pnpm/@tauri-apps+plugin-opener@2.5.0/node_modules/@tauri-apps/plugin-opener", |
||||||
|
"link": true |
||||||
|
}, |
||||||
|
"node_modules/tailwindcss": { |
||||||
|
"version": "4.1.14", |
||||||
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", |
||||||
|
"integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", |
||||||
|
"dev": true, |
||||||
|
"license": "MIT" |
||||||
|
}, |
||||||
|
"node_modules/typescript": { |
||||||
|
"resolved": "../../node_modules/.pnpm/typescript@5.6.3/node_modules/typescript", |
||||||
|
"link": true |
||||||
|
}, |
||||||
|
"node_modules/vite": { |
||||||
|
"resolved": "../../node_modules/.pnpm/vite@7.1.10_@types+node@24.3.0_jiti@2.6.1_lightningcss@1.30.1_yaml@2.8.1/node_modules/vite", |
||||||
|
"link": true |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,21 +1,48 @@ |
|||||||
{ |
{ |
||||||
"name": "nextgraph", |
"name": "@ng-org/ng-app", |
||||||
"private": true, |
"private": true, |
||||||
"version": "0.1.0", |
"version": "0.1.2", |
||||||
"type": "module", |
"type": "module", |
||||||
"scripts": { |
"scripts": { |
||||||
"dev": "vite", |
"dev": "vite", |
||||||
"build": "tsc && vite build", |
"build": "vite build", |
||||||
"preview": "vite preview", |
"preview": "vite preview", |
||||||
"tauri": "tauri" |
"tauri": "tauri", |
||||||
|
"format": "prettier --write .", |
||||||
|
"check": "svelte-check --tsconfig ./tsconfig.json", |
||||||
|
"webdev": "cross-env NG_ENV_WEB=1 TAURI_DEBUG=1 NG_PUBLIC_DEV=1 vite", |
||||||
|
"webbuild": "cross-env NG_ENV_WEB=1 NG_ENV_ONEFILE=1 vite build && node prepare-web-file.cjs", |
||||||
|
"libwasm": "cd ../.. && cargo install cargo-run-script && cargo run-script libwasm && cd app/nextgraph", |
||||||
|
"buildfrontdev": "pnpm -C ../../infra/ngnet/bootstrap builddev && pnpm -C ../../infra/ngnet/auth builddev && pnpm -C ../../infra/ngnet/redir builddev" |
||||||
}, |
}, |
||||||
"dependencies": { |
"dependencies": { |
||||||
|
"@ark-ui/svelte": "^5.11.0", |
||||||
|
"@dvcol/svelte-simple-router": "^2.7.2", |
||||||
|
"@ng-org/lib-wasm": "workspace:*", |
||||||
|
"@ng-org/ui-common": "workspace:*", |
||||||
"@tauri-apps/api": "^2", |
"@tauri-apps/api": "^2", |
||||||
"@tauri-apps/plugin-opener": "^2" |
"@tauri-apps/plugin-opener": "^2", |
||||||
|
"async-proxy": "^0.4.1" |
||||||
}, |
}, |
||||||
"devDependencies": { |
"devDependencies": { |
||||||
"@tauri-apps/cli": "^2", |
"@hazycora/vite-plugin-svelte-svg": "^2.4.3", |
||||||
"vite": "^6.0.3", |
"@sveltejs/vite-plugin-svelte": "^6.2.1", |
||||||
"typescript": "~5.6.2" |
"@tailwindcss/typography": "^0.5.19", |
||||||
|
"@tailwindcss/vite": "^4.1.14", |
||||||
|
"@tauri-apps/cli": "^2.8.4", |
||||||
|
"@tsconfig/svelte": "^5.0.5", |
||||||
|
"cross-env": "^10.1.0", |
||||||
|
"daisyui": "^5.3.1", |
||||||
|
"node-gzip": "^1.1.2", |
||||||
|
"prettier": "^3.6.2", |
||||||
|
"prettier-plugin-svelte": "^3.4.0", |
||||||
|
"svelte": "^5.39.13", |
||||||
|
"svelte-check": "^4.3.3", |
||||||
|
"tailwindcss": "^4.1.14", |
||||||
|
"typescript": "~5.6.2", |
||||||
|
"vite": "^7.1.7", |
||||||
|
"vite-plugin-singlefile": "^2.3.0", |
||||||
|
"vite-plugin-top-level-await": "^1.6.0", |
||||||
|
"vite-plugin-wasm": "^3.5.0" |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,32 @@ |
|||||||
|
const crypto = require('crypto'); |
||||||
|
const fs = require('fs'); |
||||||
|
const {gzip, } = require('node-gzip'); |
||||||
|
|
||||||
|
var algorithm = 'sha256' |
||||||
|
, shasum = crypto.createHash(algorithm) |
||||||
|
|
||||||
|
const sha_file = './dist-web/index.sha256'; |
||||||
|
const gzip_file = './dist-web/index.gzip'; |
||||||
|
var filename = './dist-web/index.html' |
||||||
|
, s = fs.ReadStream(filename) |
||||||
|
|
||||||
|
var bufs = []; |
||||||
|
s.on('data', function(data) { |
||||||
|
shasum.update(data) |
||||||
|
bufs.push(data); |
||||||
|
}) |
||||||
|
|
||||||
|
s.on('end', function() { |
||||||
|
var hash = shasum.digest('hex') |
||||||
|
console.log(hash + ' ' + filename) |
||||||
|
|
||||||
|
fs.writeFileSync(sha_file, hash, 'utf8'); |
||||||
|
|
||||||
|
var buf = Buffer.concat(bufs); |
||||||
|
gzip(buf).then((compressed) => {fs.writeFileSync(gzip_file, compressed);}); |
||||||
|
|
||||||
|
fs.rm(filename,()=>{}); |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@ |
|||||||
|
<!-- |
||||||
|
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers |
||||||
|
// All rights reserved. |
||||||
|
// Licensed under the Apache License, Version 2.0 |
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0> |
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, |
||||||
|
// at your option. All files in the project carrying such |
||||||
|
// notice may not be copied, modified, or distributed except |
||||||
|
// according to those terms. |
||||||
|
--> |
||||||
|
|
||||||
|
<script lang="ts"> |
||||||
|
import ng from "@ng-org/ui-common/api"; |
||||||
|
import Logo from "./assets/logo.svg?component"; |
||||||
|
console.log(await ng.locales()); |
||||||
|
let info = await ng.client_info(); |
||||||
|
console.log(info.V0.details); |
||||||
|
window.ng_spa_loaded = true; |
||||||
|
if (window.ng_supported) { |
||||||
|
console.log("READY"); |
||||||
|
window.everything_ready(); |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<div class="grid h-screen place-items-center"> |
||||||
|
<div style="height:144px;"> |
||||||
|
<Logo class="w-25"/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<style> |
||||||
|
|
||||||
|
</style> |
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,34 @@ |
|||||||
|
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||||
|
// All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
|
||||||
|
import * as web_api from "@ng-org/lib-wasm"; |
||||||
|
import {init_api} from "@ng-org/ui-common/api"; |
||||||
|
init_api(web_api); |
||||||
|
|
||||||
|
const NEW_VERSION = "0.1.2-alpha.1"; |
||||||
|
|
||||||
|
// cleaning old wallets :(
|
||||||
|
try { |
||||||
|
let version = localStorage.getItem("ng_wallet_version"); |
||||||
|
if (!version || version != NEW_VERSION) { |
||||||
|
localStorage.clear(); |
||||||
|
sessionStorage.clear(); |
||||||
|
localStorage.setItem("ng_wallet_version",NEW_VERSION) |
||||||
|
} |
||||||
|
} |
||||||
|
catch (e) { |
||||||
|
// it is ok to fail. it means access denied for local storage.
|
||||||
|
} |
||||||
|
|
||||||
|
import { mount } from "svelte"; |
||||||
|
import App from "./App.svelte"; |
||||||
|
|
||||||
|
const app = mount(App, { target: document.getElementById("app") as Element }); |
||||||
|
|
||||||
|
export default app; |
@ -1,22 +1,19 @@ |
|||||||
import { invoke } from "@tauri-apps/api/core"; |
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||||
|
// All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
|
||||||
let greetInputEl: HTMLInputElement | null; |
import native_api from "./native-api"; |
||||||
let greetMsgEl: HTMLElement | null; |
import {init_api} from "@ng-org/ui-common/api"; |
||||||
|
init_api(native_api); |
||||||
|
|
||||||
async function greet() { |
import { mount } from "svelte"; |
||||||
if (greetMsgEl && greetInputEl) { |
import App from "./App.svelte"; |
||||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
||||||
greetMsgEl.textContent = await invoke("greet", { |
|
||||||
name: greetInputEl.value, |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", () => { |
const app = mount(App, { target: document.getElementById("app") as Element }); |
||||||
greetInputEl = document.querySelector("#greet-input"); |
|
||||||
greetMsgEl = document.querySelector("#greet-msg"); |
export default app; |
||||||
document.querySelector("#greet-form")?.addEventListener("submit", (e) => { |
|
||||||
e.preventDefault(); |
|
||||||
greet(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
@ -0,0 +1,335 @@ |
|||||||
|
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||||
|
// All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
import {createAsyncProxy} from "async-proxy"; |
||||||
|
import { Bowser } from "../../../sdk/js/lib-wasm/jsland/bowser.js";
|
||||||
|
import {version} from '../package.json'; |
||||||
|
import { Window } from '@tauri-apps/api/window'; |
||||||
|
import { invoke } from "@tauri-apps/api/core"; |
||||||
|
import { listen } from "@tauri-apps/api/event"; |
||||||
|
|
||||||
|
const mapping = { |
||||||
|
"privkey_to_string": ["privkey"], |
||||||
|
"wallet_gen_shuffle_for_pazzle_opening": ["pazzle_length"], |
||||||
|
"wallet_gen_shuffle_for_pin": [], |
||||||
|
"wallet_open_with_pazzle": ["wallet","pazzle","pin"], |
||||||
|
"wallet_open_with_mnemonic_words": ["wallet","mnemonic_words","pin"], |
||||||
|
"wallet_open_with_mnemonic": ["wallet","mnemonic","pin"], |
||||||
|
"wallet_was_opened": ["opened_wallet"], |
||||||
|
"wallet_create": ["params"], |
||||||
|
"wallet_read_file": ["file"], |
||||||
|
"wallet_get_file": ["wallet_name"], |
||||||
|
"wallet_import": ["encrypted_wallet","opened_wallet","in_memory"], |
||||||
|
"wallet_export_rendezvous": ["session_id", "code"], |
||||||
|
"wallet_export_get_qrcode": ["session_id", "size"], |
||||||
|
"wallet_export_get_textcode": ["session_id"], |
||||||
|
"wallet_import_rendezvous": ["size"], |
||||||
|
"wallet_import_from_code": ["code"], |
||||||
|
"wallet_close": ["wallet_name"], |
||||||
|
"encode_create_account": ["payload"], |
||||||
|
"session_start": ["wallet_name","user"], |
||||||
|
"session_start_remote": ["wallet_name","user","peer_id"], |
||||||
|
"session_stop": ["user_id"], |
||||||
|
"get_wallets": [], |
||||||
|
"open_window": ["url","label","title"], |
||||||
|
"decode_invitation": ["invite"], |
||||||
|
"user_connect": ["info","user_id","location"], |
||||||
|
"user_disconnect": ["user_id"], |
||||||
|
"discrete_update": ["session_id", "update", "heads", "crdt", "nuri"], |
||||||
|
"app_request": ["request"], |
||||||
|
"app_request_with_nuri_command": ["nuri", "command", "session_id", "payload"], |
||||||
|
"sparql_query": ["session_id","sparql","base","nuri"], |
||||||
|
"sparql_update": ["session_id","sparql","nuri"], |
||||||
|
"test": [ ], |
||||||
|
"get_device_name": [], |
||||||
|
"doc_create": [ "session_id", "crdt", "class_name", "destination", "store_repo" ], |
||||||
|
"doc_fetch_private_subscribe": [], |
||||||
|
"doc_fetch_repo_subscribe": ["repo_o"], |
||||||
|
"branch_history": ["session_id", "nuri"], |
||||||
|
"file_save_to_downloads": ["session_id", "reference", "filename", "branch_nuri"], |
||||||
|
"signature_status": ["session_id", "nuri"], |
||||||
|
"signed_snapshot_request": ["session_id", "nuri"], |
||||||
|
"signature_request": ["session_id", "nuri"], |
||||||
|
"update_header": ["session_id","nuri","title","about"], |
||||||
|
"fetch_header": ["session_id", "nuri"], |
||||||
|
"retrieve_ng_bootstrap": ["location"], |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
let lastStreamId = 0; |
||||||
|
|
||||||
|
const tauri_handler = { |
||||||
|
async apply(target, path, caller, args) { |
||||||
|
try { |
||||||
|
if (path[0] === "open_window") { |
||||||
|
let callback = args[3]; |
||||||
|
await invoke(path[0],{url:args[0],label:args[1],title:args[2]}); |
||||||
|
|
||||||
|
let unsub_register_accepted; |
||||||
|
let unsub_register_error; |
||||||
|
let unsub_register_close; |
||||||
|
|
||||||
|
const unsub_register = function() { |
||||||
|
if (unsub_register_accepted) unsub_register_accepted(); |
||||||
|
if (unsub_register_error) unsub_register_error(); |
||||||
|
if (unsub_register_close) unsub_register_close(); |
||||||
|
unsub_register_close = undefined; |
||||||
|
unsub_register_error = undefined; |
||||||
|
unsub_register_accepted = undefined; |
||||||
|
}; |
||||||
|
|
||||||
|
unsub_register_accepted = await listen( |
||||||
|
"accepted", |
||||||
|
async (event) => { |
||||||
|
unsub_register(); |
||||||
|
let reg_popup = Window.getByLabel("registration"); |
||||||
|
await reg_popup.close(); |
||||||
|
await (callback)("accepted",event.payload); |
||||||
|
} |
||||||
|
); |
||||||
|
unsub_register_error = await listen("error", async (event) => { |
||||||
|
unsub_register(); |
||||||
|
let reg_popup = Window.getByLabel("registration"); |
||||||
|
await reg_popup.close(); |
||||||
|
await (callback)("error",event.payload); |
||||||
|
}); |
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000)); |
||||||
|
let reg_popup = Window.getByLabel("registration"); |
||||||
|
unsub_register_close = await reg_popup.onCloseRequested(async (event) => { |
||||||
|
unsub_register_close = undefined; |
||||||
|
unsub_register(); |
||||||
|
}); |
||||||
|
|
||||||
|
return unsub_register; |
||||||
|
} else if (path[0] === "client_info") { |
||||||
|
let from_rust = await invoke("client_info_rust",{}); |
||||||
|
let tauri_platform = import.meta.env.TAURI_ENV_PLATFORM; |
||||||
|
let client_type; |
||||||
|
switch (tauri_platform) { |
||||||
|
case 'macos': client_type = "NativeMacOS";break; |
||||||
|
case 'linux': client_type = "NativeLinux";break; |
||||||
|
case 'windows': client_type = "NativeWin";break; |
||||||
|
case 'android': client_type = "NativeAndroid";break; |
||||||
|
case 'ios': client_type = "NativeIos";break; |
||||||
|
} |
||||||
|
let info = Bowser.parse(window.navigator.userAgent); |
||||||
|
// info.os.type = import.meta.env.TAURI_ENV_PLATFORM_TYPE;
|
||||||
|
info.os.family = import.meta.env.TAURI_ENV_FAMILY; |
||||||
|
info.os.version_tauri = import.meta.env.TAURI_ENV_PLATFORM_VERSION; |
||||||
|
info.os.version_uname = from_rust.uname.version; |
||||||
|
info.os.name_rust = from_rust.rust.os_name; |
||||||
|
info.os.name_uname = from_rust.uname.os_name; |
||||||
|
info.platform.arch = import.meta.env.TAURI_ENV_ARCH; |
||||||
|
info.platform.debug = import.meta.env.TAURI_ENV_DEBUG; |
||||||
|
info.platform.target = import.meta.env.TAURI_ENV_TARGET_TRIPLE; |
||||||
|
info.platform.arch_uname = from_rust.uname.arch; |
||||||
|
info.platform.bitness = from_rust.uname.bitness; |
||||||
|
info.platform.codename = from_rust.uname.codename || undefined; |
||||||
|
info.platform.edition = from_rust.uname.edition || undefined; |
||||||
|
info.browser.ua = window.navigator.userAgent; |
||||||
|
let res = { |
||||||
|
// TODO: install timestamp
|
||||||
|
V0 : { client_type, details: JSON.stringify(info), version, timestamp_install:0, timestamp_updated:0 } |
||||||
|
}; |
||||||
|
//console.log(info,res);
|
||||||
|
return res; |
||||||
|
} else if (path[0] === "get_device_name") { |
||||||
|
let tauri_platform = import.meta.env.TAURI_ENV_PLATFORM; |
||||||
|
if (tauri_platform == 'android') return "Android Phone"; |
||||||
|
else if (tauri_platform == 'ios') return "iPhone"; |
||||||
|
else return await invoke(path[0],{}); |
||||||
|
} else if (path[0] === "locales") { |
||||||
|
let from_rust = await invoke("locales",{}); |
||||||
|
let from_js = window.navigator.languages; |
||||||
|
console.log(from_rust,from_js); |
||||||
|
for (let lang of from_js) { |
||||||
|
let split = lang.split("-"); |
||||||
|
if (split[1]) { |
||||||
|
lang = split[0] + "-" + split[1].toUpperCase(); |
||||||
|
} |
||||||
|
if (!from_rust.includes(lang)) { from_rust.push(lang);} |
||||||
|
} |
||||||
|
return from_rust; |
||||||
|
|
||||||
|
} else if (path[0] === "disconnections_subscribe") { |
||||||
|
let callback = args[0]; |
||||||
|
let unlisten = await Window.getCurrent().listen("disconnections", (event) => { |
||||||
|
callback(event.payload).then(()=> {}) |
||||||
|
}) |
||||||
|
await invoke(path[0],{}); |
||||||
|
return () => { |
||||||
|
unlisten(); |
||||||
|
} |
||||||
|
} else if (path[0] === "user_connect") { |
||||||
|
let arg = {}; |
||||||
|
args.map((el,ix) => arg[mapping[path[0]][ix]]=el) |
||||||
|
let ret = await invoke(path[0],arg); |
||||||
|
for (let e of Object.entries(ret)) { |
||||||
|
e[1].since = new Date(e[1].since); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
else if (path[0] === "file_get") { |
||||||
|
let stream_id = (lastStreamId += 1).toString(); |
||||||
|
//console.log("stream_id",stream_id);
|
||||||
|
//let session_id = args[0];
|
||||||
|
let callback = args[3]; |
||||||
|
|
||||||
|
let unlisten = await Window.getCurrent().listen(stream_id, async (event) => { |
||||||
|
//console.log(event.payload);
|
||||||
|
if (event.payload.V0.FileBinary) { |
||||||
|
event.payload.V0.FileBinary = Uint8Array.from(event.payload.V0.FileBinary); |
||||||
|
} |
||||||
|
let ret = callback(event.payload); |
||||||
|
if (ret === true) { |
||||||
|
await invoke("cancel_stream", {stream_id}); |
||||||
|
} else if (ret.then) { |
||||||
|
ret.then(async (val)=> {
|
||||||
|
if (val === true) { |
||||||
|
await invoke("cancel_stream", {stream_id}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}) |
||||||
|
try { |
||||||
|
await invoke("file_get",{stream_id, session_id:args[0], reference: args[1], branch_nuri:args[2]}); |
||||||
|
} catch (e) { |
||||||
|
unlisten(); |
||||||
|
await invoke("cancel_stream", {stream_id}); |
||||||
|
throw e; |
||||||
|
}
|
||||||
|
return () => { |
||||||
|
unlisten(); |
||||||
|
tauri.invoke("cancel_stream", {stream_id}); |
||||||
|
} |
||||||
|
|
||||||
|
} else if (path[0] === "discrete_update") { |
||||||
|
let arg = {}; |
||||||
|
args.map((el,ix) => arg[mapping[path[0]][ix]]=el) |
||||||
|
arg.update = Array.from(new Uint8Array(arg.update)); |
||||||
|
return await invoke(path[0],arg) |
||||||
|
} else if (path[0] === "app_request_stream") { |
||||||
|
let stream_id = (lastStreamId += 1).toString(); |
||||||
|
//console.log("stream_id",stream_id);
|
||||||
|
//let session_id = args[0];
|
||||||
|
let request = args[0]; |
||||||
|
let callback = args[1]; |
||||||
|
|
||||||
|
let unlisten = await Window.getCurrent().listen(stream_id, async (event) => { |
||||||
|
//console.log(event.payload);
|
||||||
|
if (event.payload.V0.FileBinary) { |
||||||
|
event.payload.V0.FileBinary = Uint8Array.from(event.payload.V0.FileBinary); |
||||||
|
} |
||||||
|
if (event.payload.V0.State?.graph?.triples) { |
||||||
|
let json_str = new TextDecoder().decode(Uint8Array.from(event.payload.V0.State.graph.triples)); |
||||||
|
event.payload.V0.State.graph.triples = JSON.parse(json_str); |
||||||
|
} else if (event.payload.V0.Patch?.graph) { |
||||||
|
let inserts_json_str = new TextDecoder().decode(Uint8Array.from(event.payload.V0.Patch.graph.inserts)); |
||||||
|
event.payload.V0.Patch.graph.inserts = JSON.parse(inserts_json_str); |
||||||
|
let removes_json_str = new TextDecoder().decode(Uint8Array.from(event.payload.V0.Patch.graph.removes)); |
||||||
|
event.payload.V0.Patch.graph.removes = JSON.parse(removes_json_str); |
||||||
|
} |
||||||
|
if (event.payload.V0.State?.discrete) { |
||||||
|
let crdt = Object.getOwnPropertyNames(event.payload.V0.State.discrete)[0]; |
||||||
|
event.payload.V0.State.discrete[crdt] = Uint8Array.from(event.payload.V0.State.discrete[crdt]); |
||||||
|
} else if (event.payload.V0.Patch?.discrete) {
|
||||||
|
let crdt = Object.getOwnPropertyNames(event.payload.V0.Patch.discrete)[0]; |
||||||
|
event.payload.V0.Patch.discrete[crdt] = Uint8Array.from(event.payload.V0.Patch.discrete[crdt]); |
||||||
|
} |
||||||
|
let ret = callback(event.payload); |
||||||
|
if (ret === true) { |
||||||
|
await invoke("cancel_stream", {stream_id}); |
||||||
|
} else if (ret.then) { |
||||||
|
ret.then(async (val)=> {
|
||||||
|
if (val === true) { |
||||||
|
await invoke("cancel_stream", {stream_id}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}) |
||||||
|
try { |
||||||
|
await invoke("app_request_stream",{stream_id, request}); |
||||||
|
} catch (e) { |
||||||
|
unlisten(); |
||||||
|
await invoke("cancel_stream", {stream_id}); |
||||||
|
throw e; |
||||||
|
}
|
||||||
|
return () => { |
||||||
|
unlisten(); |
||||||
|
tauri.invoke("cancel_stream", {stream_id}); |
||||||
|
} |
||||||
|
|
||||||
|
} else if (path[0] === "get_wallets") { |
||||||
|
let res = await invoke(path[0],{}); |
||||||
|
if (res) for (let e of Object.entries(res)) { |
||||||
|
e[1].wallet.V0.content.security_img = Uint8Array.from(e[1].wallet.V0.content.security_img); |
||||||
|
} |
||||||
|
return res || {}; |
||||||
|
|
||||||
|
} else if (path[0] === "wallet_import_from_code") { |
||||||
|
let arg = {}; |
||||||
|
args.map((el,ix) => arg[mapping[path[0]][ix]]=el); |
||||||
|
let res = await invoke(path[0],arg); |
||||||
|
if (res) { |
||||||
|
res.V0.content.security_img = Uint8Array.from(res.V0.content.security_img); |
||||||
|
} |
||||||
|
return res || {}; |
||||||
|
|
||||||
|
} else if (path[0] === "upload_chunk") { |
||||||
|
let session_id = args[0]; |
||||||
|
let upload_id = args[1]; |
||||||
|
let chunk = args[2]; |
||||||
|
let nuri = args[3]; |
||||||
|
chunk = Array.from(new Uint8Array(chunk)); |
||||||
|
return await invoke(path[0],{session_id, upload_id, chunk, nuri}) |
||||||
|
} else if (path[0] === "wallet_create") { |
||||||
|
let params = args[0]; |
||||||
|
params.result_with_wallet_file = false; |
||||||
|
params.security_img = Array.from(new Uint8Array(params.security_img)); |
||||||
|
return await invoke(path[0],{params}) |
||||||
|
} else if (path[0] === "wallet_read_file") { |
||||||
|
let file = args[0]; |
||||||
|
file = Array.from(new Uint8Array(file)); |
||||||
|
return await invoke(path[0],{file}) |
||||||
|
} else if (path[0] === "wallet_import") { |
||||||
|
let encrypted_wallet = args[0]; |
||||||
|
encrypted_wallet.V0.content.security_img = Array.from(new Uint8Array(encrypted_wallet.V0.content.security_img)); |
||||||
|
return await invoke(path[0],{encrypted_wallet, opened_wallet:args[1], in_memory:args[2]}) |
||||||
|
} else if (path[0] && path[0].startsWith("get_local_bootstrap")) { |
||||||
|
return false; |
||||||
|
} else if (path[0] === "get_local_url") { |
||||||
|
return false; |
||||||
|
} else if (path[0] === "wallet_open_with_pazzle" || path[0] === "wallet_open_with_mnemonic_words" || path[0] === "wallet_open_with_mnemonic") { |
||||||
|
let arg:any = {}; |
||||||
|
args.map((el,ix) => arg[mapping[path[0]][ix]]=el) |
||||||
|
let img = Array.from(new Uint8Array(arg.wallet.V0.content.security_img)); |
||||||
|
let old_content = arg.wallet.V0.content; |
||||||
|
arg.wallet = {V0:{id:arg.wallet.V0.id, sig:arg.wallet.V0.sig, content:{}}}; |
||||||
|
Object.assign(arg.wallet.V0.content,old_content); |
||||||
|
arg.wallet.V0.content.security_img = img; |
||||||
|
return await invoke(path[0],arg); |
||||||
|
} else { |
||||||
|
let arg = {}; |
||||||
|
args.map((el,ix) => arg[mapping[path[0]][ix]]=el) |
||||||
|
return await invoke(path[0],arg) |
||||||
|
} |
||||||
|
} catch (e) { |
||||||
|
let error; |
||||||
|
try { |
||||||
|
error = JSON.parse(e); |
||||||
|
} catch (f) { |
||||||
|
error = e; |
||||||
|
} |
||||||
|
throw error; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const tauri_api = createAsyncProxy({}, tauri_handler); |
||||||
|
|
||||||
|
export default tauri_api; |
@ -1,116 +1,3 @@ |
|||||||
.logo.vite:hover { |
@import "tailwindcss"; |
||||||
filter: drop-shadow(0 0 2em #747bff); |
@plugin "daisyui"; |
||||||
} |
@plugin "@tailwindcss/typography"; |
||||||
|
|
||||||
.logo.typescript:hover { |
|
||||||
filter: drop-shadow(0 0 2em #2d79c7); |
|
||||||
} |
|
||||||
:root { |
|
||||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif; |
|
||||||
font-size: 16px; |
|
||||||
line-height: 24px; |
|
||||||
font-weight: 400; |
|
||||||
|
|
||||||
color: #0f0f0f; |
|
||||||
background-color: #f6f6f6; |
|
||||||
|
|
||||||
font-synthesis: none; |
|
||||||
text-rendering: optimizeLegibility; |
|
||||||
-webkit-font-smoothing: antialiased; |
|
||||||
-moz-osx-font-smoothing: grayscale; |
|
||||||
-webkit-text-size-adjust: 100%; |
|
||||||
} |
|
||||||
|
|
||||||
.container { |
|
||||||
margin: 0; |
|
||||||
padding-top: 10vh; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
justify-content: center; |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
|
|
||||||
.logo { |
|
||||||
height: 6em; |
|
||||||
padding: 1.5em; |
|
||||||
will-change: filter; |
|
||||||
transition: 0.75s; |
|
||||||
} |
|
||||||
|
|
||||||
.logo.tauri:hover { |
|
||||||
filter: drop-shadow(0 0 2em #24c8db); |
|
||||||
} |
|
||||||
|
|
||||||
.row { |
|
||||||
display: flex; |
|
||||||
justify-content: center; |
|
||||||
} |
|
||||||
|
|
||||||
a { |
|
||||||
font-weight: 500; |
|
||||||
color: #646cff; |
|
||||||
text-decoration: inherit; |
|
||||||
} |
|
||||||
|
|
||||||
a:hover { |
|
||||||
color: #535bf2; |
|
||||||
} |
|
||||||
|
|
||||||
h1 { |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
|
|
||||||
input, |
|
||||||
button { |
|
||||||
border-radius: 8px; |
|
||||||
border: 1px solid transparent; |
|
||||||
padding: 0.6em 1.2em; |
|
||||||
font-size: 1em; |
|
||||||
font-weight: 500; |
|
||||||
font-family: inherit; |
|
||||||
color: #0f0f0f; |
|
||||||
background-color: #ffffff; |
|
||||||
transition: border-color 0.25s; |
|
||||||
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); |
|
||||||
} |
|
||||||
|
|
||||||
button { |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
|
|
||||||
button:hover { |
|
||||||
border-color: #396cd8; |
|
||||||
} |
|
||||||
button:active { |
|
||||||
border-color: #396cd8; |
|
||||||
background-color: #e8e8e8; |
|
||||||
} |
|
||||||
|
|
||||||
input, |
|
||||||
button { |
|
||||||
outline: none; |
|
||||||
} |
|
||||||
|
|
||||||
#greet-input { |
|
||||||
margin-right: 5px; |
|
||||||
} |
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) { |
|
||||||
:root { |
|
||||||
color: #f6f6f6; |
|
||||||
background-color: #2f2f2f; |
|
||||||
} |
|
||||||
|
|
||||||
a:hover { |
|
||||||
color: #24c8db; |
|
||||||
} |
|
||||||
|
|
||||||
input, |
|
||||||
button { |
|
||||||
color: #ffffff; |
|
||||||
background-color: #0f0f0f98; |
|
||||||
} |
|
||||||
button:active { |
|
||||||
background-color: #0f0f0f69; |
|
||||||
} |
|
||||||
} |
|
||||||
|
@ -0,0 +1,11 @@ |
|||||||
|
// svelte.config.js
|
||||||
|
export default { |
||||||
|
compilerOptions: { |
||||||
|
experimental: { |
||||||
|
async: true |
||||||
|
} |
||||||
|
}, |
||||||
|
vitePlugin: { |
||||||
|
//inspector: true
|
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,11 @@ |
|||||||
|
/** @type {import('tailwindcss').Config} */ |
||||||
|
export default { |
||||||
|
content: ["./src/**/*.{html,js,svelte,ts}"], |
||||||
|
theme: { |
||||||
|
extend: {} |
||||||
|
}, |
||||||
|
plugins: [], |
||||||
|
daisyui: { |
||||||
|
//themes: ['valentine']
|
||||||
|
} |
||||||
|
}; |
@ -1,43 +1,167 @@ |
|||||||
import { defineConfig } from "vite"; |
import tailwindcss from "@tailwindcss/vite"; |
||||||
|
import { defineConfig, UserConfig } from "vite"; |
||||||
|
import { svelte } from "@sveltejs/vite-plugin-svelte"; |
||||||
|
import { viteSingleFile } from "vite-plugin-singlefile" |
||||||
|
import svelteSVG from "@hazycora/vite-plugin-svelte-svg"; |
||||||
|
import wasm from "vite-plugin-wasm"; |
||||||
|
import topLevelAwait from "vite-plugin-top-level-await"; |
||||||
|
|
||||||
// @ts-expect-error process is a nodejs global
|
|
||||||
const host = process.env.TAURI_DEV_HOST; |
const host = process.env.TAURI_DEV_HOST; |
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig(async () => ({ |
export default defineConfig((): UserConfig => { |
||||||
|
const worker_plugins = []; |
||||||
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
const config = { |
||||||
//
|
worker: { |
||||||
// 1. prevent Vite from obscuring rust errors
|
format: 'es', |
||||||
clearScreen: false, |
plugins : [ |
||||||
// 2. tauri expects a fixed port, fail if that port is not available
|
] |
||||||
server: { |
}, |
||||||
port: 5173, |
plugins: [ |
||||||
strictPort: true, |
tailwindcss(),
|
||||||
host: host || false, |
svelte(), |
||||||
hmr: host |
svelteSVG({ |
||||||
? { |
svgoConfig: { |
||||||
protocol: "ws", |
plugins: [ |
||||||
host, |
{ |
||||||
port: 1421, |
name: 'preset-default', |
||||||
|
params: { |
||||||
|
overrides: { |
||||||
|
// disable plugins
|
||||||
|
removeViewBox: false, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: 'prefixIds', |
||||||
|
} |
||||||
|
], |
||||||
|
}, // See https://github.com/svg/svgo#configuration
|
||||||
|
requireSuffix: true, // Set false to accept '.svg' without the '?component'
|
||||||
|
}), |
||||||
|
], |
||||||
|
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
||||||
|
//
|
||||||
|
// 1. prevent Vite from obscuring rust errors
|
||||||
|
clearScreen: false, |
||||||
|
// 2. tauri expects a fixed port, fail if that port is not available
|
||||||
|
server: { |
||||||
|
port: process.env.NG_ENV_WEB ? 1421 : 1420, |
||||||
|
strictPort: true, |
||||||
|
host: host || false, |
||||||
|
hmr: host |
||||||
|
? { |
||||||
|
protocol: "ws", |
||||||
|
host, |
||||||
|
port: process.env.NG_ENV_WEB ? 1421 : 1420, |
||||||
|
} |
||||||
|
: undefined, |
||||||
|
watch: { |
||||||
|
// 3. tell Vite to ignore watching `src-tauri`
|
||||||
|
ignored: ["**/src-tauri/**"] |
||||||
|
} |
||||||
|
}, |
||||||
|
publicDir: process.env.NG_PUBLIC_DEV ? "public_dev" : false, |
||||||
|
// Env variables starting with the item of `envPrefix` will be exposed in tauri's source code through `import.meta.env`.
|
||||||
|
envPrefix: ["VITE_", "TAURI_ENV_", "NG_ENV_"], |
||||||
|
build: { |
||||||
|
outDir: process.env.NG_ENV_WEB ? "dist-web" : "dist", |
||||||
|
// Tauri uses Chromium on Windows and WebKit on macOS and Linux
|
||||||
|
target: process.env.TAURI_ENV_PLATFORM == "windows" ? "chrome105" : "safari13", |
||||||
|
// don't minify for debug builds
|
||||||
|
minify: !process.env.TAURI_ENV_DEBUG ? "esbuild" : false, |
||||||
|
// produce sourcemaps for debug builds
|
||||||
|
sourcemap: !!process.env.TAURI_ENV_DEBUG |
||||||
|
} |
||||||
|
}; |
||||||
|
if (process.env.NG_ENV_WEB) { |
||||||
|
if (process.env.NG_ENV_ONEFILE) { |
||||||
|
config.plugins.push(viteSingleFile()); |
||||||
|
worker_plugins.push(viteSingleFile()); |
||||||
|
config.plugins.push( |
||||||
|
{ |
||||||
|
name: 'move-script-body', |
||||||
|
transformIndexHtml: { |
||||||
|
order: 'post', |
||||||
|
handler: function transform(html) { |
||||||
|
let scriptTag = html.match(/<script type[^>]*>(.*?)<\/script[^>]*>/)[0] |
||||||
|
//console.log("\n SCRIPT TAG", scriptTag, "\n")
|
||||||
|
html = html.replace(scriptTag, "") |
||||||
|
html = html.replace("<!-- # INSERT SCRIPT HERE -->", scriptTag) |
||||||
|
return html; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
} |
} |
||||||
: undefined, |
config.plugins.push(topLevelAwait()); |
||||||
watch: { |
config.plugins.push(wasm()); |
||||||
// 3. tell Vite to ignore watching `src-tauri`
|
worker_plugins.push(topLevelAwait()); |
||||||
ignored: ["**/src-tauri/**"], |
worker_plugins.push(wasm()); |
||||||
}, |
config.plugins.push( |
||||||
}, |
{ |
||||||
// Env variables starting with the item of `envPrefix` will be exposed in tauri's source code through `import.meta.env`.
|
name: 'inject-web-script', |
||||||
envPrefix: ['VITE_', 'TAURI_ENV_*'], |
transformIndexHtml: { |
||||||
build: { |
order: 'pre', // Tells Vite to run this before other processes
|
||||||
// Tauri uses Chromium on Windows and WebKit on macOS and Linux
|
handler: function transform() { |
||||||
target: |
return [ |
||||||
process.env.TAURI_ENV_PLATFORM == 'windows' |
{ |
||||||
? 'chrome105' |
tag: "script", |
||||||
: 'safari13', |
children: "check_supported=true;", |
||||||
// don't minify for debug builds
|
injectTo: "head" |
||||||
minify: !process.env.TAURI_ENV_DEBUG ? 'esbuild' : false, |
}, |
||||||
// produce sourcemaps for debug builds
|
{ |
||||||
sourcemap: !!process.env.TAURI_ENV_DEBUG, |
tag: "script", |
||||||
}, |
attrs: { |
||||||
})); |
"type": "module", |
||||||
|
"src": "/src/main-web.ts", |
||||||
|
"defer": true |
||||||
|
}, |
||||||
|
injectTo: "head" |
||||||
|
}] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
} else { |
||||||
|
config.plugins.push( |
||||||
|
{ |
||||||
|
name: 'inject-native-script', |
||||||
|
transformIndexHtml: { |
||||||
|
order: 'pre', // Tells Vite to run this before other processes
|
||||||
|
handler: function transform() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
tag: "script", |
||||||
|
children: "check_supported=false;", |
||||||
|
injectTo: "head" |
||||||
|
}, |
||||||
|
{ |
||||||
|
tag: "script", |
||||||
|
attrs: { |
||||||
|
"type": "module", |
||||||
|
"src": "/src/main.ts", |
||||||
|
"defer": true |
||||||
|
}, |
||||||
|
injectTo: "head" |
||||||
|
}] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
config.plugins.push( |
||||||
|
{ |
||||||
|
name: 'make-script-defer', |
||||||
|
transformIndexHtml: { |
||||||
|
order: 'post', |
||||||
|
handler: function transform(html) { |
||||||
|
let new_html = html.replace("<script type","<script defer type"); |
||||||
|
return new_html; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
config.worker.plugins = () => {return worker_plugins;}; |
||||||
|
return config; |
||||||
|
}); |
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,86 @@ |
|||||||
|
# JS SDK of NextGraph |
||||||
|
|
||||||
|
## NextGraph |
||||||
|
|
||||||
|
> NextGraph brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. |
||||||
|
> |
||||||
|
> This open source ecosystem provides solutions for end-users (a platform) and software developers (a framework), wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with **end-to-end encryption**, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers. |
||||||
|
> |
||||||
|
> More info here [https://nextgraph.org](https://nextgraph.org) |
||||||
|
|
||||||
|
## WASM module |
||||||
|
|
||||||
|
The [lib-wasm](../lib-wasm/README.md) crate contains the WASM module. |
||||||
|
|
||||||
|
## Examples |
||||||
|
|
||||||
|
- an example of web app using the vite bundler `example-webapp-vite` |
||||||
|
- an example of React web app `app-react` |
||||||
|
- an example of node-js app `app-node` |
||||||
|
- `index.html` an example of vanilla JS usage of the SDK |
||||||
|
|
||||||
|
## Support |
||||||
|
|
||||||
|
Documentation can be found here [https://docs.nextgraph.org](https://docs.nextgraph.org) |
||||||
|
|
||||||
|
And our community forum where you can ask questions is here [https://forum.nextgraph.org](https://forum.nextgraph.org) |
||||||
|
|
||||||
|
## For developers |
||||||
|
|
||||||
|
Read our [getting started guide](https://docs.nextgraph.org/en/getting-started/). |
||||||
|
|
||||||
|
``` |
||||||
|
// for nodejs |
||||||
|
npm i nextgraph |
||||||
|
// or for browser |
||||||
|
npm i nextgraphweb |
||||||
|
``` |
||||||
|
|
||||||
|
## Publishing to npm |
||||||
|
|
||||||
|
``` |
||||||
|
cargo run-script node |
||||||
|
cd pkg-node |
||||||
|
npm login --auth-type legacy |
||||||
|
npm publish --auth-type legacy |
||||||
|
``` |
||||||
|
|
||||||
|
### Example Plain JS web app (with Vite) |
||||||
|
|
||||||
|
see [README here](example-webapp-vite/README.md) |
||||||
|
|
||||||
|
### Example React web app |
||||||
|
|
||||||
|
``` |
||||||
|
cd ../app-react |
||||||
|
npm run dev |
||||||
|
``` |
||||||
|
|
||||||
|
This URL will open automatically in browser : [http://localhost:8080](http://localhost:8080) |
||||||
|
|
||||||
|
### Example NodeJS app |
||||||
|
|
||||||
|
``` |
||||||
|
cd ../app-node |
||||||
|
npm run start |
||||||
|
``` |
||||||
|
|
||||||
|
### Contributions license |
||||||
|
|
||||||
|
Unless you explicitly state otherwise, any contribution intentionally submitted |
||||||
|
for inclusion in the work by you shall be dual licensed as below, without any |
||||||
|
additional terms or conditions. |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
Licensed under either of |
||||||
|
|
||||||
|
- Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0) |
||||||
|
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) |
||||||
|
at your option. |
||||||
|
|
||||||
|
`SPDX-License-Identifier: Apache-2.0 OR MIT` |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
NextGraph received funding through the [NGI Assure Fund](https://nlnet.nl/assure) and the [NGI Zero Commons Fund](https://nlnet.nl/commonsfund/), both funds established by [NLnet](https://nlnet.nl/) Foundation with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreements No 957073 and No 101092990, respectively. |
@ -0,0 +1,181 @@ |
|||||||
|
# This file is autogenerated by maturin v1.8.2 |
||||||
|
# To update, run |
||||||
|
# |
||||||
|
# maturin generate-ci github |
||||||
|
# |
||||||
|
name: CI |
||||||
|
|
||||||
|
on: |
||||||
|
push: |
||||||
|
branches: |
||||||
|
- main |
||||||
|
- master |
||||||
|
tags: |
||||||
|
- '*' |
||||||
|
pull_request: |
||||||
|
workflow_dispatch: |
||||||
|
|
||||||
|
permissions: |
||||||
|
contents: read |
||||||
|
|
||||||
|
jobs: |
||||||
|
linux: |
||||||
|
runs-on: ${{ matrix.platform.runner }} |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
platform: |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: x86_64 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: x86 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: aarch64 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: armv7 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: s390x |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: ppc64le |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v4 |
||||||
|
- uses: actions/setup-python@v5 |
||||||
|
with: |
||||||
|
python-version: 3.x |
||||||
|
- name: Build wheels |
||||||
|
uses: PyO3/maturin-action@v1 |
||||||
|
with: |
||||||
|
target: ${{ matrix.platform.target }} |
||||||
|
args: --release --out dist --find-interpreter |
||||||
|
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} |
||||||
|
manylinux: auto |
||||||
|
- name: Upload wheels |
||||||
|
uses: actions/upload-artifact@v4 |
||||||
|
with: |
||||||
|
name: wheels-linux-${{ matrix.platform.target }} |
||||||
|
path: dist |
||||||
|
|
||||||
|
musllinux: |
||||||
|
runs-on: ${{ matrix.platform.runner }} |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
platform: |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: x86_64 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: x86 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: aarch64 |
||||||
|
- runner: ubuntu-22.04 |
||||||
|
target: armv7 |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v4 |
||||||
|
- uses: actions/setup-python@v5 |
||||||
|
with: |
||||||
|
python-version: 3.x |
||||||
|
- name: Build wheels |
||||||
|
uses: PyO3/maturin-action@v1 |
||||||
|
with: |
||||||
|
target: ${{ matrix.platform.target }} |
||||||
|
args: --release --out dist --find-interpreter |
||||||
|
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} |
||||||
|
manylinux: musllinux_1_2 |
||||||
|
- name: Upload wheels |
||||||
|
uses: actions/upload-artifact@v4 |
||||||
|
with: |
||||||
|
name: wheels-musllinux-${{ matrix.platform.target }} |
||||||
|
path: dist |
||||||
|
|
||||||
|
windows: |
||||||
|
runs-on: ${{ matrix.platform.runner }} |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
platform: |
||||||
|
- runner: windows-latest |
||||||
|
target: x64 |
||||||
|
- runner: windows-latest |
||||||
|
target: x86 |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v4 |
||||||
|
- uses: actions/setup-python@v5 |
||||||
|
with: |
||||||
|
python-version: 3.x |
||||||
|
architecture: ${{ matrix.platform.target }} |
||||||
|
- name: Build wheels |
||||||
|
uses: PyO3/maturin-action@v1 |
||||||
|
with: |
||||||
|
target: ${{ matrix.platform.target }} |
||||||
|
args: --release --out dist --find-interpreter |
||||||
|
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} |
||||||
|
- name: Upload wheels |
||||||
|
uses: actions/upload-artifact@v4 |
||||||
|
with: |
||||||
|
name: wheels-windows-${{ matrix.platform.target }} |
||||||
|
path: dist |
||||||
|
|
||||||
|
macos: |
||||||
|
runs-on: ${{ matrix.platform.runner }} |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
platform: |
||||||
|
- runner: macos-13 |
||||||
|
target: x86_64 |
||||||
|
- runner: macos-14 |
||||||
|
target: aarch64 |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v4 |
||||||
|
- uses: actions/setup-python@v5 |
||||||
|
with: |
||||||
|
python-version: 3.x |
||||||
|
- name: Build wheels |
||||||
|
uses: PyO3/maturin-action@v1 |
||||||
|
with: |
||||||
|
target: ${{ matrix.platform.target }} |
||||||
|
args: --release --out dist --find-interpreter |
||||||
|
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} |
||||||
|
- name: Upload wheels |
||||||
|
uses: actions/upload-artifact@v4 |
||||||
|
with: |
||||||
|
name: wheels-macos-${{ matrix.platform.target }} |
||||||
|
path: dist |
||||||
|
|
||||||
|
sdist: |
||||||
|
runs-on: ubuntu-latest |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v4 |
||||||
|
- name: Build sdist |
||||||
|
uses: PyO3/maturin-action@v1 |
||||||
|
with: |
||||||
|
command: sdist |
||||||
|
args: --out dist |
||||||
|
- name: Upload sdist |
||||||
|
uses: actions/upload-artifact@v4 |
||||||
|
with: |
||||||
|
name: wheels-sdist |
||||||
|
path: dist |
||||||
|
|
||||||
|
release: |
||||||
|
name: Release |
||||||
|
runs-on: ubuntu-latest |
||||||
|
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} |
||||||
|
needs: [linux, musllinux, windows, macos, sdist] |
||||||
|
permissions: |
||||||
|
# Use to sign the release artifacts |
||||||
|
id-token: write |
||||||
|
# Used to upload release artifacts |
||||||
|
contents: write |
||||||
|
# Used to generate artifact attestation |
||||||
|
attestations: write |
||||||
|
steps: |
||||||
|
- uses: actions/download-artifact@v4 |
||||||
|
- name: Generate artifact attestation |
||||||
|
uses: actions/attest-build-provenance@v1 |
||||||
|
with: |
||||||
|
subject-path: 'wheels-*/*' |
||||||
|
- name: Publish to PyPI |
||||||
|
if: ${{ startsWith(github.ref, 'refs/tags/') }} |
||||||
|
uses: PyO3/maturin-action@v1 |
||||||
|
env: |
||||||
|
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} |
||||||
|
with: |
||||||
|
command: upload |
||||||
|
args: --non-interactive --skip-existing wheels-*/* |
@ -0,0 +1,72 @@ |
|||||||
|
/target |
||||||
|
.env/ |
||||||
|
# Byte-compiled / optimized / DLL files |
||||||
|
__pycache__/ |
||||||
|
.pytest_cache/ |
||||||
|
*.py[cod] |
||||||
|
|
||||||
|
# C extensions |
||||||
|
*.so |
||||||
|
|
||||||
|
# Distribution / packaging |
||||||
|
.Python |
||||||
|
.venv/ |
||||||
|
env/ |
||||||
|
bin/ |
||||||
|
build/ |
||||||
|
develop-eggs/ |
||||||
|
dist/ |
||||||
|
eggs/ |
||||||
|
lib/ |
||||||
|
lib64/ |
||||||
|
parts/ |
||||||
|
sdist/ |
||||||
|
var/ |
||||||
|
include/ |
||||||
|
man/ |
||||||
|
venv/ |
||||||
|
*.egg-info/ |
||||||
|
.installed.cfg |
||||||
|
*.egg |
||||||
|
|
||||||
|
# Installer logs |
||||||
|
pip-log.txt |
||||||
|
pip-delete-this-directory.txt |
||||||
|
pip-selfcheck.json |
||||||
|
|
||||||
|
# Unit test / coverage reports |
||||||
|
htmlcov/ |
||||||
|
.tox/ |
||||||
|
.coverage |
||||||
|
.cache |
||||||
|
nosetests.xml |
||||||
|
coverage.xml |
||||||
|
|
||||||
|
# Translations |
||||||
|
*.mo |
||||||
|
|
||||||
|
# Mr Developer |
||||||
|
.mr.developer.cfg |
||||||
|
.project |
||||||
|
.pydevproject |
||||||
|
|
||||||
|
# Rope |
||||||
|
.ropeproject |
||||||
|
|
||||||
|
# Django stuff: |
||||||
|
*.log |
||||||
|
*.pot |
||||||
|
|
||||||
|
.DS_Store |
||||||
|
|
||||||
|
# Sphinx documentation |
||||||
|
docs/_build/ |
||||||
|
|
||||||
|
# PyCharm |
||||||
|
.idea/ |
||||||
|
|
||||||
|
# VSCode |
||||||
|
.vscode/ |
||||||
|
|
||||||
|
# Pyenv |
||||||
|
.python-version |
@ -0,0 +1,25 @@ |
|||||||
|
[package] |
||||||
|
name = "ng-sdk-python" |
||||||
|
version.workspace = true |
||||||
|
description = "NextGraph python package. Nextgraph is a decentralized, secure and local-first web 3.0 ecosystem based on Semantic Web and CRDTs" |
||||||
|
edition.workspace = true |
||||||
|
license.workspace = true |
||||||
|
authors.workspace = true |
||||||
|
repository.workspace = true |
||||||
|
homepage.workspace = true |
||||||
|
keywords = [ "crdt","e2ee","local-first","p2p","semantic-web" ] |
||||||
|
documentation.workspace = true |
||||||
|
rust-version.workspace = true |
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||||
|
[lib] |
||||||
|
name = "nextgraphpy" |
||||||
|
crate-type = ["cdylib"] |
||||||
|
|
||||||
|
[dependencies] |
||||||
|
pyo3 = "0.23.3" |
||||||
|
pyo3-async-runtimes = { version = "0.23", features = ["async-std-runtime"] } |
||||||
|
pythonize = "0.23.0" |
||||||
|
async-std = "1.12.0" |
||||||
|
serde = { version = "1.0.142", features = ["derive"] } |
||||||
|
nextgraph = { path = "../rust" } |
@ -0,0 +1,63 @@ |
|||||||
|
<p align="center"> |
||||||
|
<img src="https://git.nextgraph.org/NextGraph/nextgraph-rs/raw/branch/master/nextgraph/.static/header.png" alt="nextgraph-header" /> |
||||||
|
</p> |
||||||
|
|
||||||
|
# nextgraphpy |
||||||
|
|
||||||
|
![MSRV][rustc-image] |
||||||
|
[![Apache 2.0 Licensed][license-image]][license-link] |
||||||
|
[![MIT Licensed][license-image2]][license-link2] |
||||||
|
[](https://forum.nextgraph.org) |
||||||
|
[](https://pypi.org/project/nextgraphpy/) |
||||||
|
|
||||||
|
Python package for NextGraph, implemented in Rust |
||||||
|
|
||||||
|
This repository is in active development at [https://git.nextgraph.org/NextGraph/nextgraph-rs](https://git.nextgraph.org/NextGraph/nextgraph-rs), a Gitea instance. For bug reports, issues, merge requests, and in order to join the dev team, please visit the link above and create an account (you can do so with a github account). The [github repo](https://github.com/nextgraph-org/nextgraph-rs) is just a read-only mirror that does not accept issues. |
||||||
|
|
||||||
|
## NextGraph |
||||||
|
|
||||||
|
> NextGraph brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. |
||||||
|
> |
||||||
|
> This open source ecosystem provides solutions for end-users (a platform) and software developers (a framework), wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with **end-to-end encryption**, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers. |
||||||
|
> |
||||||
|
> More info here [https://nextgraph.org](https://nextgraph.org) |
||||||
|
|
||||||
|
## Support |
||||||
|
|
||||||
|
Documentation can be found here [https://docs.nextgraph.org](https://docs.nextgraph.org) |
||||||
|
|
||||||
|
And our community forum where you can ask questions is here [https://forum.nextgraph.org](https://forum.nextgraph.org) |
||||||
|
|
||||||
|
[](https://fosstodon.org/@nextgraph) |
||||||
|
|
||||||
|
## How to use NextGraph App & Platform |
||||||
|
|
||||||
|
NextGraph is in alpha release! |
||||||
|
|
||||||
|
You can try it online or by installing the apps. Please follow our [Getting started](https://docs.nextgraph.org/en/getting-started/) guide . |
||||||
|
|
||||||
|
You can also subscribe to [our newsletter](https://list.nextgraph.org/subscription/form) to get updates, and support us with a [donation](https://nextgraph.org/donate/). |
||||||
|
|
||||||
|
## NextGraph is also a Framework for App developers |
||||||
|
|
||||||
|
Read our [getting started guide for developers](https://docs.nextgraph.org/en/framework/getting-started/). |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
Licensed under either of |
||||||
|
|
||||||
|
- Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0) |
||||||
|
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) |
||||||
|
at your option. |
||||||
|
|
||||||
|
`SPDX-License-Identifier: Apache-2.0 OR MIT` |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
NextGraph received funding through the [NGI Assure Fund](https://nlnet.nl/assure) and the [NGI Zero Commons Fund](https://nlnet.nl/commonsfund/), both funds established by [NLnet](https://nlnet.nl/) Foundation with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreements No 957073 and No 101092990, respectively. |
||||||
|
|
||||||
|
[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg |
||||||
|
[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg |
||||||
|
[license-link]: https://git.nextgraph.org/NextGraph/nextgraph-rs/raw/branch/master/LICENSE-APACHE2 |
||||||
|
[license-image2]: https://img.shields.io/badge/license-MIT-blue.svg |
||||||
|
[license-link2]: https://git.nextgraph.org/NextGraph/nextgraph-rs/src/branch/master/LICENSE-MIT |
@ -0,0 +1,17 @@ |
|||||||
|
[build-system] |
||||||
|
requires = ["maturin>=1.8,<2.0"] |
||||||
|
build-backend = "maturin" |
||||||
|
|
||||||
|
[project] |
||||||
|
name = "nextgraphpy" |
||||||
|
requires-python = ">=3.7.3" |
||||||
|
description = "NextGraph brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs." |
||||||
|
readme = "README.md" |
||||||
|
classifiers = [ |
||||||
|
"Programming Language :: Rust", |
||||||
|
"Programming Language :: Python :: Implementation :: CPython", |
||||||
|
"Programming Language :: Python :: Implementation :: PyPy", |
||||||
|
] |
||||||
|
version = "0.1a1.dev4" |
||||||
|
[tool.maturin] |
||||||
|
features = ["pyo3/extension-module"] |
@ -0,0 +1,167 @@ |
|||||||
|
// Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||||
|
// All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
|
||||||
|
use pyo3::exceptions::PyTypeError; |
||||||
|
use pyo3::prelude::*; |
||||||
|
use pythonize::{depythonize, pythonize}; |
||||||
|
use serde::{Deserialize, Serialize}; |
||||||
|
|
||||||
|
use std::fs::read; |
||||||
|
|
||||||
|
#[allow(unused_imports)] |
||||||
|
use ::nextgraph::local_broker::{ |
||||||
|
app_request, app_request_stream, doc_fetch_repo_subscribe, init_local_broker, session_start, |
||||||
|
session_stop, user_connect, user_disconnect, wallet_close, wallet_create_v0, wallet_get, |
||||||
|
wallet_get_file, wallet_import, wallet_read_file, wallet_was_opened, LocalBrokerConfig, |
||||||
|
SessionConfig, |
||||||
|
}; |
||||||
|
use ::nextgraph::net::app_protocol::*; |
||||||
|
use ::nextgraph::net::types::BootstrapContentV0; |
||||||
|
use ::nextgraph::repo::errors::NgError; |
||||||
|
use ::nextgraph::repo::log::*; |
||||||
|
use ::nextgraph::repo::types::{BranchCrdt, StoreRepo, PubKey}; |
||||||
|
use ::nextgraph::wallet::types::{CreateWalletV0, SessionInfo}; |
||||||
|
use ::nextgraph::wallet::{display_mnemonic, emojis::display_pazzle}; |
||||||
|
use async_std::stream::StreamExt; |
||||||
|
|
||||||
|
#[pyfunction] |
||||||
|
fn init_local_broker_in_memory() -> PyResult<()> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
|
||||||
|
struct PyNgError(NgError); |
||||||
|
|
||||||
|
impl From<PyNgError> for PyErr { |
||||||
|
fn from(e: PyNgError) -> PyErr { |
||||||
|
let ioe: std::io::Error = e.0.into(); |
||||||
|
ioe.into() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<NgError> for PyNgError { |
||||||
|
fn from(e: NgError) -> PyNgError { |
||||||
|
PyNgError(e) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// Open the wallet with mnemonic and PIN, and returns the wallet_name and the SessionInfo
|
||||||
|
#[pyfunction] |
||||||
|
fn wallet_open_with_mnemonic_words( |
||||||
|
py: Python, |
||||||
|
wallet_file_path: String, |
||||||
|
mnemonic_words: Vec<String>, |
||||||
|
pin: [u8; 4], |
||||||
|
) -> PyResult<Bound<PyAny>> { |
||||||
|
pyo3_async_runtimes::async_std::future_into_py(py, async move { |
||||||
|
init_local_broker(Box::new(|| LocalBrokerConfig::InMemory)).await; |
||||||
|
|
||||||
|
let wallet_file = read(wallet_file_path).expect("read wallet file"); |
||||||
|
|
||||||
|
let wallet = wallet_read_file(wallet_file) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
let opened_wallet = ::nextgraph::local_broker::wallet_open_with_mnemonic_words( |
||||||
|
&wallet, |
||||||
|
&mnemonic_words, |
||||||
|
pin, |
||||||
|
) |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
let user_id = opened_wallet.personal_identity(); |
||||||
|
let wallet_name = opened_wallet.name(); |
||||||
|
|
||||||
|
let _client = wallet_import(wallet.clone(), opened_wallet, true) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
let session = session_start(SessionConfig::new_in_memory(&user_id, &wallet_name)) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
// let session = session_start(SessionConfig::new_remote(&user_id, &wallet_name, None)).await?;
|
||||||
|
|
||||||
|
let _status = user_connect(&user_id) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
let s = Python::with_gil(|py| pythonize(py, &session).unwrap().unbind()); |
||||||
|
Ok((wallet_name, s)) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
#[pyfunction] |
||||||
|
#[pyo3(signature = (session_id, sparql, nuri=None))] |
||||||
|
fn doc_sparql_update( |
||||||
|
py: Python, |
||||||
|
session_id: u64, |
||||||
|
sparql: String, |
||||||
|
nuri: Option<String>, |
||||||
|
) -> PyResult<Bound<PyAny>> { |
||||||
|
pyo3_async_runtimes::async_std::future_into_py(py, async move { |
||||||
|
let res = ::nextgraph::local_broker::doc_sparql_update(session_id, sparql, nuri) |
||||||
|
.await |
||||||
|
.map_err(|e| PyTypeError::new_err(e))?; |
||||||
|
Ok(res) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
#[pyfunction] |
||||||
|
fn disconnect_and_close<'a>( |
||||||
|
py: Python<'a>, |
||||||
|
user_id: Bound<'a, PyAny>, |
||||||
|
wallet_name: String, |
||||||
|
) -> PyResult<Bound<'a, PyAny>> { |
||||||
|
let user_id: PubKey = depythonize(&user_id)?; |
||||||
|
pyo3_async_runtimes::async_std::future_into_py(py, async move { |
||||||
|
user_disconnect(&user_id) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
// stop the session
|
||||||
|
session_stop(&user_id) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
|
||||||
|
// closes the wallet
|
||||||
|
wallet_close(&wallet_name) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))?; |
||||||
|
Ok(()) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
#[pyfunction] |
||||||
|
#[pyo3(signature = (session_id, crdt, class_name, destination="store".to_string(), store_type=None, store_repo=None))] |
||||||
|
fn doc_create( |
||||||
|
py: Python, |
||||||
|
session_id: u64, |
||||||
|
crdt: String, |
||||||
|
class_name: String, |
||||||
|
destination: String, |
||||||
|
store_type: Option<String>, |
||||||
|
store_repo: Option<String>, |
||||||
|
) -> PyResult<Bound<PyAny>> { |
||||||
|
pyo3_async_runtimes::async_std::future_into_py(py, async move { |
||||||
|
|
||||||
|
Ok(nextgraph::local_broker::doc_create(session_id, crdt, class_name, destination, store_type, store_repo) |
||||||
|
.await |
||||||
|
.map_err(|e| Into::<PyNgError>::into(e))? |
||||||
|
) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
#[pymodule] |
||||||
|
fn nextgraphpy(m: &Bound<'_, PyModule>) -> PyResult<()> { |
||||||
|
m.add_function(wrap_pyfunction!(wallet_open_with_mnemonic_words, m)?)?; |
||||||
|
m.add_function(wrap_pyfunction!(doc_sparql_update, m)?)?; |
||||||
|
m.add_function(wrap_pyfunction!(disconnect_and_close, m)?)?; |
||||||
|
m.add_function(wrap_pyfunction!(doc_create, m)?)?; |
||||||
|
Ok(()) |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
import asyncio |
||||||
|
from nextgraphpy import wallet_open_with_mnemonic_words, doc_create, doc_sparql_update, disconnect_and_close |
||||||
|
|
||||||
|
async def main(): |
||||||
|
wallet_session = await wallet_open_with_mnemonic_words( |
||||||
|
"/home/nn/Downloads/wallet-bCHhOmlelVtZ60jjGu7m-YtzF4TfD5WyErAMnEDOn-kA.ngw", |
||||||
|
["mutual", "wife", "section", "actual", "spend", "illness", "save", "delay", "kiss", "crash", "baby", "degree" ], |
||||||
|
[2, 3, 2, 3]) |
||||||
|
wallet_name = wallet_session[0] |
||||||
|
session_info = wallet_session[1] |
||||||
|
session_id = session_info["session_id"] |
||||||
|
print(wallet_name) |
||||||
|
print(session_info) |
||||||
|
doc_id = await doc_create(session_id, "Graph", "data:graph", "store") |
||||||
|
print(doc_id) |
||||||
|
commits = await doc_sparql_update(session_id, |
||||||
|
"INSERT DATA { <did:ng:_> <example:predicate> \"An example value22\". }", doc_id) |
||||||
|
print(commits) |
||||||
|
await disconnect_and_close(session_info["user"], wallet_name) |
||||||
|
|
||||||
|
asyncio.run(main()) |
Loading…
Reference in new issue