parent
1039c2694d
commit
bf8bdd94b9
@ -1,14 +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> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="stylesheet" href="/src/styles.css" /> |
||||
<link |
||||
rel="icon" |
||||
type="image/svg+xml" |
||||
href="data:image/svg+xml;base64, |
||||
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> |
||||
<script type="module" src="/src/main.ts" defer></script> |
||||
<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> |
||||
<div id="app"></div> |
||||
<div id="splash" class="splashing"> |
||||
<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="noshow" style="text-align:center;" id="app-loading"> Loading ...</div> |
||||
|
||||
<div id="error-no-wasm" style="padding-left:15px;" class="error-no-wasm-hidden"> |
||||
Your browser is too old or is miss-configured. |
||||
Please try one of those options:<br/><br/> |
||||
- Upgrade to a newer version of this browser.<br/> |
||||
- Try with another browser software.<br/> |
||||
- <a href="https://nextgraph.org/download">install our native apps for |
||||
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> |
||||
|
@ -1,34 +1,48 @@ |
||||
{ |
||||
"name": "nextgraph", |
||||
"name": "@ng-org/ng-app", |
||||
"private": true, |
||||
"version": "0.1.0", |
||||
"version": "0.1.2", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "vite", |
||||
"build": "tsc && vite build", |
||||
"build": "vite build", |
||||
"preview": "vite preview", |
||||
"tauri": "tauri", |
||||
"format": "prettier --write .", |
||||
"check": "svelte-check --tsconfig ./tsconfig.json" |
||||
"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": { |
||||
"@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/plugin-opener": "^2" |
||||
"@tauri-apps/plugin-opener": "^2", |
||||
"async-proxy": "^0.4.1" |
||||
}, |
||||
"devDependencies": { |
||||
"@hazycora/vite-plugin-svelte-svg": "^2.4.3", |
||||
"@sveltejs/vite-plugin-svelte": "^6.2.1", |
||||
"@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": "^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
@ -1,23 +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 role="alert" class="alert alert-info"> |
||||
<p class="text-3xl font-bold underline">Hello world!</p> |
||||
<div class="grid h-screen place-items-center"> |
||||
<div style="height:144px;"> |
||||
<Logo class="w-25"/> |
||||
</div> |
||||
</div> |
||||
|
||||
<article class="prose lg:prose-xl"> |
||||
<h1>Garlic bread with cheese: What the science tells us</h1> |
||||
<p> |
||||
For years parents have espoused the health benefits of eating garlic bread with cheese to |
||||
their children, with the food earning such an iconic status in our culture that kids will |
||||
often dress up as warm, cheesy loaf for Halloween. |
||||
</p> |
||||
<p> |
||||
But a recent study shows that the celebrated appetizer may be linked to a series of rabies |
||||
cases springing up around the country. |
||||
</p> |
||||
</article> |
||||
|
||||
<style> |
||||
|
||||
</style> |
||||
|
After Width: | Height: | Size: 2.9 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; |
@ -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,41 +1,167 @@ |
||||
import tailwindcss from "@tailwindcss/vite"; |
||||
import { defineConfig } from "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"; |
||||
|
||||
const host = process.env.TAURI_DEV_HOST; |
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({ |
||||
plugins: [tailwindcss(), svelte()], |
||||
// 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: 5173, |
||||
strictPort: true, |
||||
host: host || false, |
||||
hmr: host |
||||
? { |
||||
protocol: "ws", |
||||
host, |
||||
port: 1421 |
||||
} |
||||
: undefined, |
||||
watch: { |
||||
// 3. tell Vite to ignore watching `src-tauri`
|
||||
ignored: ["**/src-tauri/**"] |
||||
export default defineConfig((): UserConfig => { |
||||
const worker_plugins = []; |
||||
const config = { |
||||
worker: { |
||||
format: 'es', |
||||
plugins : [ |
||||
] |
||||
}, |
||||
plugins: [ |
||||
tailwindcss(),
|
||||
svelte(), |
||||
svelteSVG({ |
||||
svgoConfig: { |
||||
plugins: [ |
||||
{ |
||||
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 ? 5184 : 5183, |
||||
} |
||||
: 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 |
||||
} |
||||
}, |
||||
// Env variables starting with the item of `envPrefix` will be exposed in tauri's source code through `import.meta.env`.
|
||||
envPrefix: ["VITE_", "TAURI_ENV_*"], |
||||
build: { |
||||
// 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; |
||||
} |
||||
} |
||||
} |
||||
); |
||||
} |
||||
config.plugins.push(topLevelAwait()); |
||||
config.plugins.push(wasm()); |
||||
worker_plugins.push(topLevelAwait()); |
||||
worker_plugins.push(wasm()); |
||||
config.plugins.push( |
||||
{ |
||||
name: 'inject-web-script', |
||||
transformIndexHtml: { |
||||
order: 'pre', // Tells Vite to run this before other processes
|
||||
handler: function transform() { |
||||
return [ |
||||
{ |
||||
tag: "script", |
||||
children: "check_supported=true;", |
||||
injectTo: "head" |
||||
}, |
||||
{ |
||||
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