SPARQL Query viewer

pull/37/head
Niko PLP 2 months ago
parent 95ed77e414
commit 029276e205
  1. 1
      nextgraph/src/lib.rs
  2. 2
      ng-app/package.json
  3. 119
      ng-app/src/apps/SparqlQueryEditor.svelte
  4. 16
      ng-app/src/apps/SparqlUpdateEditor.svelte
  5. 81
      ng-app/src/apps/TurtleViewer.svelte
  6. 4
      ng-app/src/classes.ts
  7. 4
      ng-app/src/locales/en.json
  8. 2
      ng-app/src/routes/WalletInfo.svelte
  9. 17
      ng-app/src/store.ts
  10. 5
      ng-app/src/styles.css
  11. 139
      ng-app/src/turtle.js
  12. 8
      ng-app/src/zeras.ts
  13. 70
      ng-sdk-js/src/lib.rs
  14. 10
      ng-verifier/src/lib.rs
  15. 3
      ng-verifier/src/request_processor.rs
  16. 15
      pnpm-lock.yaml

@ -94,6 +94,7 @@ pub mod verifier {
pub use ng_net::app_protocol::*; pub use ng_net::app_protocol::*;
} }
pub use ng_verifier::prepare_app_response_for_js; pub use ng_verifier::prepare_app_response_for_js;
pub use ng_verifier::triples_ser_to_json_string;
} }
pub mod wallet { pub mod wallet {

@ -44,6 +44,7 @@
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"highlight.js": "^11.10.0",
"internal-ip": "^7.0.0", "internal-ip": "^7.0.0",
"node-gzip": "^1.1.2", "node-gzip": "^1.1.2",
"postcss": "^8.4.23", "postcss": "^8.4.23",
@ -52,6 +53,7 @@
"svelte": "^3.54.0", "svelte": "^3.54.0",
"svelte-check": "^3.0.0", "svelte-check": "^3.0.0",
"svelte-heros-v2": "^0.10.12", "svelte-heros-v2": "^0.10.12",
"svelte-highlight": "^7.7.0",
"svelte-preprocess": "^5.0.3", "svelte-preprocess": "^5.0.3",
"svelte-time": "^0.8.0", "svelte-time": "^0.8.0",
"tailwindcss": "^3.3.1", "tailwindcss": "^3.3.1",

@ -0,0 +1,119 @@
<!--
// Copyright (c) 2022-2024 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 { onMount, tick, onDestroy } from "svelte";
import {
sparql_query,
toast_error,
toast_success,
reset_toasts
} from "../store";
import {
in_memory_discrete, open_viewer, set_viewer
} from "../tab";
import{ Sun, RocketLaunch } from "svelte-heros-v2";
import { t } from "svelte-i18n";
import { Table, TableBody, TableBodyCell, TableBodyRow, TableHead, TableHeadCell, Toggle } from 'flowbite-svelte';
import CodeMirror from "svelte-codemirror-editor";
import {StreamLanguage} from "@codemirror/language"
import { sparql } from "@codemirror/legacy-modes/mode/sparql";
import {basicSetup} from "codemirror"
import Highlight, { LineNumbers } from "svelte-highlight";
import hljs from "highlight.js";
import { definer } from "../turtle";
import "svelte-highlight/styles/github.css";
import { each } from "svelte/internal";
const language = {
name: "turtle",
register: (hljs) => {
return definer(hljs);
},
};
onMount(()=>{
if (!$in_memory_discrete){
$in_memory_discrete = "SELECT ?subject ?predicate ?object WHERE {\n ?subject ?predicate ?object .\n} LIMIT 10";
}
});
let union = false;
const run = async () => {
try{
reset_toasts();
results = await sparql_query($in_memory_discrete, union);
} catch(e) {
toast_error(e);
}
}
const openTurtle = () => {
reset_toasts();
set_viewer("n:g:z:rdf_viewer:turtle");
}
let results = undefined;
</script>
<div class="flex-col">
<CodeMirror bind:value={$in_memory_discrete} lineWrapping useTab={false} extensions={[basicSetup,StreamLanguage.define(sparql)]} styles={{
"&": {
maxWidth: "100%",
},
}}/>
<Toggle class="mt-1 ml-2" bind:checked={union}>Query all docs</Toggle>
<button
on:click={run}
on:keypress={run}
class="select-none ml-2 mt-2 mb-10 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
>
<RocketLaunch tabindex="-1" class="mr-2 focus:outline-none" />
Run Query
</button>
<button
on:click={openTurtle}
on:keypress={openTurtle}
class="select-none ml-2 mt-2 mb-10 text-gray-600 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
>
<Sun class="mr-2 focus:outline-none" tabindex="-1" />
View Graph
</button>
{#if results!==undefined}
<div>
<span class="ml-2 font-bold">Results: <br/></span>
{#if Array.isArray(results)}
<Highlight {language} code={results.join(" .\r\n") + " ."} class="mb-10" let:highlighted >
<LineNumbers {highlighted} wrapLines hideBorder />
</Highlight>
{:else if results?.head}
<Table>
<TableHead>
{#each results.head.vars as variable}
<TableHeadCell>{variable}</TableHeadCell>
{/each}
</TableHead>
<TableBody tableBodyClass="divide-y">
{#each results.results.bindings as row}
<TableBodyRow>
{#each results.head.vars as variable}
<TableBodyCell class="px-6 py-4 whitespace-break-spaces font-medium">{row[variable].value}</TableBodyCell>
{/each}
</TableBodyRow>
{/each}
</TableBody>
</Table>
{:else}
<span class="ml-2">{results}</span>
{/if}
</div>
{/if}
</div>

@ -14,7 +14,8 @@
import { import {
sparql_update, sparql_update,
toast_error, toast_error,
toast_success toast_success,
reset_toasts,
} from "../store"; } from "../store";
import { import {
in_memory_discrete, open_viewer in_memory_discrete, open_viewer
@ -31,20 +32,21 @@
onMount(()=>{ onMount(()=>{
if (!$in_memory_discrete){ if (!$in_memory_discrete){
$in_memory_discrete = "INSERT DATA { \n <did:ng:test> <test:predicate> \"An example value\".\r}"; $in_memory_discrete = "INSERT DATA { \n <did:ng:test> <test:predicate> \"An example value\".\r}";
// "SELECT * WHERE {\r\
// ?subject ?predicate ?object .\r\
// } LIMIT 10";
} }
}); });
const run = async () => { const run = async () => {
try{ try{
reset_toasts();
await sparql_update($in_memory_discrete); await sparql_update($in_memory_discrete);
toast_success($t("app.sparql_update_editor.success")); toast_success($t("app.sparql_update_editor.success"));
} catch(e) { } catch(e) {
toast_error(e); toast_error(e);
} }
} }
const openViewer = () => {
reset_toasts();
open_viewer();
}
</script> </script>
<div class="flex-col"> <div class="flex-col">
@ -63,8 +65,8 @@
Run Update Run Update
</button> </button>
<button <button
on:click={open_viewer} on:click={openViewer}
on:keypress={open_viewer} on:keypress={openViewer}
class="select-none ml-2 mt-2 mb-10 text-gray-600 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55" class="select-none ml-2 mt-2 mb-10 text-gray-600 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
> >
<Sun class="mr-2 focus:outline-none" tabindex="-1" /> <Sun class="mr-2 focus:outline-none" tabindex="-1" />

@ -0,0 +1,81 @@
<!--
// Copyright (c) 2022-2024 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 { onMount, tick, onDestroy } from "svelte";
import {
sparql_update,
toast_error,
toast_success
} from "../store";
import {
in_memory_discrete, open_viewer, set_viewer, set_editor, set_view_or_edit, cur_tab
} from "../tab";
import{ PencilSquare, RocketLaunch } from "svelte-heros-v2";
import { t } from "svelte-i18n";
import { Button, Progressbar, Spinner, Alert } from "flowbite-svelte";
import Highlight, { LineNumbers } from "svelte-highlight";
import hljs from "highlight.js";
import { definer } from "../turtle";
import "svelte-highlight/styles/github.css";
const language = {
name: "turtle",
register: (hljs) => {
return definer(hljs);
},
};
export let commits = {graph:[]};
let source = "";
$: source = commits.graph.join(" .\r\n") + " .";
const openQuery = () => {
set_viewer("n:g:z:sparql_query");
}
const openUpdate = () => {
set_editor("n:g:z:sparql_update");
set_view_or_edit(false);
}
onMount(()=>{
});
</script>
<div class="flex-col">
<button
on:click={openQuery}
on:keypress={openQuery}
class="select-none ml-2 mt-2 mb-2 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
>
<RocketLaunch tabindex="-1" class="mr-2 focus:outline-none" />
SPARQL Query
</button>
{#if $cur_tab.doc.can_edit}
<button
on:click={openUpdate}
on:keypress={openUpdate}
class="select-none ml-2 mt-2 text-gray-600 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
>
<PencilSquare class="mr-2 focus:outline-none" tabindex="-1" />
SPARQL Update
</button>
{/if}
<Highlight {language} code={source} class="mb-10" let:highlighted >
<LineNumbers {highlighted} wrapLines hideBorder />
</Highlight>
</div>

@ -200,7 +200,7 @@ export const official_classes = {
"ng:n": "SPARQL Query", // edited with YASGUI or Sparnatural, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master "ng:n": "SPARQL Query", // edited with YASGUI or Sparnatural, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:a": "Saved SPARQL Query that can be invoked", "ng:a": "Saved SPARQL Query that can be invoked",
"ng:o": "n:g:z:sparql:invoke", "ng:o": "n:g:z:sparql:invoke",
"ng:w": "n:g:z:sparql_query:yasgui", "ng:w": "n:g:z:sparql_query",
"ng:compat": ["code:sparql", "file:iana:application:sparql-query","file:iana:application:x-sparql-query"], "ng:compat": ["code:sparql", "file:iana:application:sparql-query","file:iana:application:x-sparql-query"],
}, },
"query:sparql_update": { "query:sparql_update": {
@ -208,7 +208,7 @@ export const official_classes = {
"ng:n": "SPARQL Update", // edited with YASGUI, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master "ng:n": "SPARQL Update", // edited with YASGUI, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:a": "Saved SPARQL Update that can be invoked", "ng:a": "Saved SPARQL Update that can be invoked",
"ng:o": "n:g:z:sparql:invoke", "ng:o": "n:g:z:sparql:invoke",
"ng:w": "n:g:z:sparql_update:yasgui", "ng:w": "n:g:z:sparql_update",
"ng:compat": ["code:sparql", "file:iana:application:sparql-update"], "ng:compat": ["code:sparql", "file:iana:application:sparql-update"],
}, },
"query:graphql": { "query:graphql": {

@ -218,7 +218,7 @@
"remove_wallet": "Remove wallet from Device", "remove_wallet": "Remove wallet from Device",
"remove_wallet_modal.title": "Remove wallet?", "remove_wallet_modal.title": "Remove wallet?",
"remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?", "remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?",
"create_text_code": "Generate TextCode to export", "create_text_code": "Export by generating a TextCode",
"scan_qr.title": "Export by scanning a QR-Code", "scan_qr.title": "Export by scanning a QR-Code",
"scan_qr.no_camera": "If to the contrary, the other device does not have a camera, ", "scan_qr.no_camera": "If to the contrary, the other device does not have a camera, ",
"scan_qr.other_has_camera": "If the other device where you want to import the Wallet, has a camera, then you can just click on the Back button and select <span class=\"path\">Generate QR to export</span>", "scan_qr.other_has_camera": "If the other device where you want to import the Wallet, has a camera, then you can just click on the Back button and select <span class=\"path\">Generate QR to export</span>",
@ -459,7 +459,7 @@
}, },
"wallet_login_textcode": { "wallet_login_textcode": {
"title": "Import Wallet from TextCode", "title": "Import Wallet from TextCode",
"description": "To generate a TextCode, open a logged in device and go to<br /><span class=\"path\">User Panel > Wallet > Generate TextCode to export</span>.", "description": "To generate a TextCode, open a logged in device and go to<br /><span class=\"path\">User Panel > Wallet > Export by generating a TextCode</span>.",
"import_btn": "Import with TextCode", "import_btn": "Import with TextCode",
"enter_here": "Enter your TextCode here below and click on Import button" "enter_here": "Enter your TextCode here below and click on Import button"
}, },

@ -195,7 +195,7 @@
<SidebarWrapper <SidebarWrapper
divClass="bg-gray-60 overflow-y-auto py-4 px-3 rounded dark:bg-gray-800" divClass="bg-gray-60 overflow-y-auto py-4 px-3 rounded dark:bg-gray-800"
> >
<SidebarGroup ulClass="space-y-2" role="menu"> <SidebarGroup ulClass="space-y-2" class="text-left" role="menu">
<li> <li>
<h2 class="text-xl mb-6">{$t("pages.wallet_info.title")}</h2> <h2 class="text-xl mb-6">{$t("pages.wallet_info.title")}</h2>
</li> </li>

@ -111,6 +111,12 @@ export const toast = function(level, text) {
}); });
} }
export const reset_toasts = function() {
toasts.update((old)=>{
return [];
});
}
export const toast_error = (text) => { export const toast_error = (text) => {
toast("error", text); toast("error", text);
} }
@ -377,13 +383,22 @@ export const digest_to_string = function(digest) {
return encode(buffer.buffer); return encode(buffer.buffer);
}; };
export const sparql_query = async function(sparql:string, union:boolean) {
let session = get(active_session);
if (!session) {
throw new Error("no session");
}
let nuri = union ? undefined : "did:ng:"+get(cur_tab).branch.nuri;
return await ng.sparql_query(session.session_id, sparql, nuri);
}
export const sparql_update = async function(sparql:string) { export const sparql_update = async function(sparql:string) {
let session = get(active_session); let session = get(active_session);
if (!session) { if (!session) {
throw new Error("no session"); throw new Error("no session");
} }
let nuri = "did:ng:"+get(cur_tab).branch.nuri; let nuri = "did:ng:"+get(cur_tab).branch.nuri;
await ng.sparql_update(session.session_id, nuri, sparql); await ng.sparql_update(session.session_id, sparql, nuri);
} }
export const branch_subscribe = function(nuri:string, in_tab:boolean) { export const branch_subscribe = function(nuri:string, in_tab:boolean) {

@ -9,6 +9,11 @@
// according to those terms. // according to those terms.
*/ */
td.hljs {
padding-left: 0 !important;
padding-right: 0 !important;
}
/** To format paths, like Settings > Wallet > Generate Wallet QR */ /** To format paths, like Settings > Wallet > Generate Wallet QR */
.path { .path {
font-family: monospace; font-family: monospace;

@ -0,0 +1,139 @@
/*
Language: Turtle
Author: Redmer KRONEMEIJER <redmer.kronemeijer@rdmr.eu>
Contributors: Mark ELLIS <mark.ellis@stardog.com>, Vladimir ALEXIEV <vladimir.alexiev@ontotext.com>
*/
function hljsDefineTurtle(hljs) {
// export default function (hljs) {
var KEYWORDS = {
keyword: "BASE|2 PREFIX|5 @base|10 @prefix|10",
literal: "true false",
built_in: "a",
};
var IRI_LITERAL = {
// https://www.w3.org/TR/turtle/#grammar-production-IRIREF
className: "literal",
relevance: 1, // XML tags look also like relative IRIs
begin: /</,
end: />/,
// illegal: /[^\x00-\x20"{}|^`\\]/, // TODO: https://www.w3.org/TR/turtle/#grammar-production-UCHAR
};
// https://www.w3.org/TR/turtle/#terminals
var PN_CHARS_BASE =
"A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u10000-\uEFFFF";
var PN_CHARS_U = PN_CHARS_BASE + "_";
var PN_CHARS = "-" + PN_CHARS_U + "0-9\u00B7\u0300-\u036F\u203F-\u2040";
var BLANK_NODE_LABEL =
"_:[" + PN_CHARS_U + "0-9]([" + PN_CHARS + ".]*[" + PN_CHARS + "])?";
var PN_PREFIX =
"[" + PN_CHARS_BASE + "]([" + PN_CHARS + ".]*[" + PN_CHARS + "])?";
var PERCENT = "%[0-9A-Fa-f][0-9A-Fa-f]";
var PN_LOCAL_ESC = "\\\\[_~.!$&'()*+,;=/?#@%-]";
var PLX = PERCENT + "|" + PN_LOCAL_ESC;
var PNAME_NS = "(" + PN_PREFIX + ")?:";
var PN_LOCAL =
"([" +
PN_CHARS_U +
":0-9]|" +
PLX +
")([" +
PN_CHARS +
".:]|" +
PLX +
")*([" +
PN_CHARS +
":]|" +
PLX +
")?";
var PNAME_LN = PNAME_NS + PN_LOCAL;
var PNAME_NS_or_LN = PNAME_NS + "(" + PN_LOCAL + ")?";
var PNAME = {
begin: PNAME_NS_or_LN,
relevance: 0,
className: "symbol",
};
var BLANK_NODE = {
begin: BLANK_NODE_LABEL,
relevance: 10,
className: "template-variable",
};
var LANGTAG = {
begin: /@[a-zA-Z]+([a-zA-Z0-9-]+)*/,
className: "type",
relevance: 0, // also catches objectivec keywords like: @protocol, @optional
};
var DATATYPE = {
begin: "\\^\\^" + PNAME_LN,
className: "type",
relevance: 10,
};
var TRIPLE_APOS_STRING = {
begin: /'''/,
end: /'''/,
className: "string",
relevance: 0,
};
var TRIPLE_QUOTE_STRING = {
begin: /"""/,
end: /"""/,
className: "string",
relevance: 0,
};
var APOS_STRING_LITERAL = JSON.parse(JSON.stringify(hljs.APOS_STRING_MODE));
APOS_STRING_LITERAL.relevance = 0;
var QUOTE_STRING_LITERAL = JSON.parse(JSON.stringify(hljs.QUOTE_STRING_MODE));
QUOTE_STRING_LITERAL.relevance = 0;
return {
name: "Turtle",
case_insensitive: true, // however `true` and `@prefix` are oblig. cased thus
keywords: KEYWORDS,
aliases: ["turtle", "ttl", "n3"],
contains: [
LANGTAG,
DATATYPE,
IRI_LITERAL,
BLANK_NODE,
PNAME,
TRIPLE_APOS_STRING,
TRIPLE_QUOTE_STRING, // order matters
APOS_STRING_LITERAL,
QUOTE_STRING_LITERAL,
hljs.C_NUMBER_MODE,
hljs.HASH_COMMENT_MODE,
],
exports: {
LANGTAG: LANGTAG,
DATATYPE: DATATYPE,
IRI_LITERAL: IRI_LITERAL,
BLANK_NODE: BLANK_NODE,
PNAME: PNAME,
TRIPLE_APOS_STRING: TRIPLE_APOS_STRING,
TRIPLE_QUOTE_STRING: TRIPLE_QUOTE_STRING,
APOS_STRING_LITERAL: APOS_STRING_LITERAL,
QUOTE_STRING_LITERAL: QUOTE_STRING_LITERAL,
NUMBER: hljs.C_NUMBER_MODE,
KEYWORDS: KEYWORDS,
},
};
}
// module.exports = function (hljs) {
// hljs.registerLanguage("turtle", hljsDefineTurtle);
// };
// module.exports.definer = hljsDefineTurtle;
export const definer = hljsDefineTurtle;

@ -85,12 +85,12 @@ export const official_apps = {
"ng:b": "TripleViewer", "ng:b": "TripleViewer",
"ng:o": ["data:graph"], "ng:o": ["data:graph"],
}, },
"n:g:z:sparql_query:yasgui": { "n:g:z:sparql_query": {
"ng:n": "SPARQL Query", "ng:n": "SPARQL Query",
"ng:a": "View, edit and invoke a Graph SPARQL query", "ng:a": "View, edit and invoke a Graph SPARQL query",
"ng:c": "app", "ng:c": "app",
"ng:u": "sparql_query",//favicon. can be a did:ng:j "ng:u": "sparql_query",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query:yasgui", "ng:g": "n:g:z:sparql_query",
"ng:b": "SparqlQueryEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui "ng:b": "SparqlQueryEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
"ng:o": ["data:graph"], "ng:o": ["data:graph"],
"ng:w": ["query:sparql"], "ng:w": ["query:sparql"],
@ -115,12 +115,12 @@ export const official_apps = {
"ng:o": ["data:graph"], "ng:o": ["data:graph"],
"ng:w": ["query:graphql"], "ng:w": ["query:graphql"],
}, },
"n:g:z:sparql_update:yasgui": { "n:g:z:sparql_update": {
"ng:n": "SPARQL Update", "ng:n": "SPARQL Update",
"ng:a": "View, edit and invoke a Graph SPARQL Update", "ng:a": "View, edit and invoke a Graph SPARQL Update",
"ng:c": "app", "ng:c": "app",
"ng:u": "sparql_query",//favicon. can be a did:ng:j "ng:u": "sparql_query",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_update:yasgui", "ng:g": "n:g:z:sparql_update",
"ng:b": "SparqlUpdateEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui "ng:b": "SparqlUpdateEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
"ng:o": [], "ng:o": [],
"ng:w": ["query:sparql_update","data:graph"], "ng:w": ["query:sparql_update","data:graph"],

@ -259,16 +259,26 @@ pub async fn session_headless_stop(session_id: JsValue, force_close: bool) -> Re
Ok(()) Ok(())
} }
/*let app_response = nextgraph::verifier::prepare_app_response_for_js(app_response)?; */
#[cfg(wasmpack_target = "nodejs")] #[cfg(wasmpack_target = "nodejs")]
#[wasm_bindgen] #[wasm_bindgen]
pub async fn sparql_query(session_id: JsValue, sparql: String) -> Result<JsValue, JsValue> { pub async fn sparql_query(
session_id: JsValue,
sparql: String,
nuri: JsValue,
) -> Result<JsValue, JsValue> {
let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id) let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id)
.map_err(|_| "Invalid session_id".to_string())?; .map_err(|_| "Invalid session_id".to_string())?;
let nuri = if nuri.is_string() {
NuriV0::new_from(&nuri.as_string().unwrap())
.map_err(|_| "Deserialization error of Nuri".to_string())?
} else {
NuriV0::new_entire_user_site()
};
let request = AppRequest::V0(AppRequestV0 { let request = AppRequest::V0(AppRequestV0 {
command: AppRequestCommandV0::new_read_query(), command: AppRequestCommandV0::new_read_query(),
nuri: NuriV0::new_entire_user_site(), nuri,
payload: Some(AppRequestPayload::new_sparql_query(sparql)), payload: Some(AppRequestPayload::new_sparql_query(sparql)),
session_id, session_id,
}); });
@ -305,8 +315,8 @@ pub async fn sparql_query(session_id: JsValue, sparql: String) -> Result<JsValue
#[wasm_bindgen] #[wasm_bindgen]
pub async fn sparql_update( pub async fn sparql_update(
session_id: JsValue, session_id: JsValue,
nuri: String,
sparql: String, sparql: String,
nuri: String,
) -> Result<(), String> { ) -> Result<(), String> {
let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id) let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id)
.map_err(|_| "Invalid session_id".to_string())?; .map_err(|_| "Invalid session_id".to_string())?;
@ -329,6 +339,58 @@ pub async fn sparql_update(
} }
} }
#[cfg(not(wasmpack_target = "nodejs"))]
#[wasm_bindgen]
pub async fn sparql_query(
session_id: JsValue,
sparql: String,
nuri: JsValue,
) -> Result<JsValue, JsValue> {
let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id)
.map_err(|_| "Invalid session_id".to_string())?;
let nuri = if nuri.is_string() {
NuriV0::new_from(&nuri.as_string().unwrap())
.map_err(|_| "Deserialization error of Nuri".to_string())?
} else {
NuriV0::new_entire_user_site()
};
let request = AppRequest::V0(AppRequestV0 {
command: AppRequestCommandV0::new_read_query(),
nuri,
payload: Some(AppRequestPayload::new_sparql_query(sparql)),
session_id,
});
let response = nextgraph::local_broker::app_request(request)
.await
.map_err(|e: NgError| e.to_string())?;
let AppResponse::V0(res) = response;
match res {
AppResponseV0::False => return Ok(JsValue::FALSE),
AppResponseV0::True => return Ok(JsValue::TRUE),
AppResponseV0::Graph(graph) => {
let triples: Vec<Triple> = serde_bare::from_slice(&graph)
.map_err(|_| "Deserialization error of Vec<Triple>".to_string())?;
Ok(JsValue::from(
triples
.into_iter()
.map(|x| JsValue::from_str(&x.to_string()))
.collect::<Array>(),
))
}
AppResponseV0::QueryResult(buf) => {
let string = String::from_utf8(buf)
.map_err(|_| "Deserialization error of JSON QueryResult String".to_string())?;
js_sys::JSON::parse(&string)
}
AppResponseV0::Error(e) => Err(e.to_string().into()),
_ => Err("invalid AppResponse".to_string().into()),
}
}
#[cfg(wasmpack_target = "nodejs")] #[cfg(wasmpack_target = "nodejs")]
#[wasm_bindgen] #[wasm_bindgen]
pub async fn rdf_dump(session_id: JsValue) -> Result<String, String> { pub async fn rdf_dump(session_id: JsValue) -> Result<String, String> {

@ -17,7 +17,7 @@ mod rocksdb_user_storage;
use ng_net::app_protocol::*; use ng_net::app_protocol::*;
use ng_oxigraph::oxrdf::Triple; use ng_oxigraph::oxrdf::Triple;
fn triples_ser_to_json_ser(ser: &Vec<u8>) -> Result<Vec<u8>, String> { pub fn triples_ser_to_json_string(ser: &Vec<u8>) -> Result<String, String> {
let triples: Vec<Triple> = serde_bare::from_slice(ser) let triples: Vec<Triple> = serde_bare::from_slice(ser)
.map_err(|_| "Deserialization error of Vec<Triple>".to_string())?; .map_err(|_| "Deserialization error of Vec<Triple>".to_string())?;
@ -26,8 +26,12 @@ fn triples_ser_to_json_ser(ser: &Vec<u8>) -> Result<Vec<u8>, String> {
triples_json.push(serde_json::Value::String(insert.to_string())); triples_json.push(serde_json::Value::String(insert.to_string()));
} }
let triples_json = serde_json::Value::Array(triples_json); let triples_json = serde_json::Value::Array(triples_json);
let json = serde_json::to_string(&triples_json) serde_json::to_string(&triples_json)
.map_err(|_| "Cannot serialize Vec<Triple> to JSON".to_string())?; .map_err(|_| "Cannot serialize Vec<Triple> to JSON".to_string())
}
fn triples_ser_to_json_ser(ser: &Vec<u8>) -> Result<Vec<u8>, String> {
let json = triples_ser_to_json_string(ser)?;
Ok(json.as_bytes().to_vec()) Ok(json.as_bytes().to_vec())
} }

@ -169,6 +169,7 @@ impl Verifier {
if update { if update {
return Err(NgError::InvalidTarget); return Err(NgError::InvalidTarget);
} else { } else {
//log_info!("QUERYING UNION GRAPH");
return Ok(None); return Ok(None);
} }
} }
@ -248,7 +249,7 @@ impl Verifier {
query, query,
)))) = payload )))) = payload
{ {
log_debug!("query={}", query); //log_debug!("query={}", query);
let store = self.graph_dataset.as_ref().unwrap(); let store = self.graph_dataset.as_ref().unwrap();
let parsed = Query::parse(&query, None); let parsed = Query::parse(&query, None);
if parsed.is_err() { if parsed.is_err() {

@ -30,6 +30,7 @@ importers:
dayjs: ^1.11.10 dayjs: ^1.11.10
flowbite: ^1.6.5 flowbite: ^1.6.5
flowbite-svelte: ^0.43.3 flowbite-svelte: ^0.43.3
highlight.js: ^11.10.0
html5-qrcode: ^2.3.8 html5-qrcode: ^2.3.8
internal-ip: ^7.0.0 internal-ip: ^7.0.0
ng-sdk-js: workspace:^0.1.0-preview.1 ng-sdk-js: workspace:^0.1.0-preview.1
@ -42,6 +43,7 @@ importers:
svelte-check: ^3.0.0 svelte-check: ^3.0.0
svelte-codemirror-editor: ^1.4.0 svelte-codemirror-editor: ^1.4.0
svelte-heros-v2: ^0.10.12 svelte-heros-v2: ^0.10.12
svelte-highlight: ^7.7.0
svelte-i18n: ^4.0.0 svelte-i18n: ^4.0.0
svelte-inview: ^4.0.2 svelte-inview: ^4.0.2
svelte-preprocess: ^5.0.3 svelte-preprocess: ^5.0.3
@ -83,6 +85,7 @@ importers:
autoprefixer: 10.4.14_postcss@8.4.24 autoprefixer: 10.4.14_postcss@8.4.24
cross-env: 7.0.3 cross-env: 7.0.3
dayjs: 1.11.10 dayjs: 1.11.10
highlight.js: 11.10.0
internal-ip: 7.0.0 internal-ip: 7.0.0
node-gzip: 1.1.2 node-gzip: 1.1.2
postcss: 8.4.24 postcss: 8.4.24
@ -91,6 +94,7 @@ importers:
svelte: 3.59.1 svelte: 3.59.1
svelte-check: 3.4.3_sxhny56dlbcmwov4vk7qwrzshi svelte-check: 3.4.3_sxhny56dlbcmwov4vk7qwrzshi
svelte-heros-v2: 0.10.12_svelte@3.59.1 svelte-heros-v2: 0.10.12_svelte@3.59.1
svelte-highlight: 7.7.0
svelte-preprocess: 5.0.4_vmz4xia4c7tzh4ii3qac2x3tom svelte-preprocess: 5.0.4_vmz4xia4c7tzh4ii3qac2x3tom
svelte-time: 0.8.0 svelte-time: 0.8.0
tailwindcss: 3.3.2 tailwindcss: 3.3.2
@ -1604,6 +1608,11 @@ packages:
function-bind: 1.1.1 function-bind: 1.1.1
dev: true dev: true
/highlight.js/11.10.0:
resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==}
engines: {node: '>=12.0.0'}
dev: true
/html5-qrcode/2.3.8: /html5-qrcode/2.3.8:
resolution: {integrity: sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==} resolution: {integrity: sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==}
dev: false dev: false
@ -2263,6 +2272,12 @@ packages:
svelte: 3.59.1 svelte: 3.59.1
dev: true dev: true
/svelte-highlight/7.7.0:
resolution: {integrity: sha512-umBiTz3fLbbNCA+wGlRhJOb54iC6ap8S/dxjauQ+g6a8oFGTOGQeOP2rJVoh/K1ssF7IjP4P0T3Yuiu+vtaG5Q==}
dependencies:
highlight.js: 11.10.0
dev: true
/svelte-hmr/0.15.2_svelte@3.59.1: /svelte-hmr/0.15.2_svelte@3.59.1:
resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==} resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
engines: {node: ^12.20 || ^14.13.1 || >= 16} engines: {node: ^12.20 || ^14.13.1 || >= 16}

Loading…
Cancel
Save