From be4ea744e7d500d735510d109664bda53aefe74a Mon Sep 17 00:00:00 2001 From: Fayeed Pawaskar Date: Tue, 28 Nov 2023 10:55:43 +0530 Subject: [PATCH 01/13] Added agent expression language --- .../centralized-agent-language/.gitignore | 15 +++ .../ConstructorIcon.svelte | 11 ++ .../centralized-agent-language/Icon.svelte | 83 ++++++++++++++ .../centralized-agent-language/README.md | 3 + .../centralized-agent-language/adapter.ts | 61 ++++++++++ .../centralized-agent-language/esbuild.ts | 22 ++++ .../expressionUI.ts | 13 +++ .../centralized-agent-language/index.ts | 34 ++++++ .../centralized-agent-language/package.json | 45 ++++++++ .../rollup.config.expression-ui.js | 25 +++++ .../rollup.config.icons.js | 106 ++++++++++++++++++ .../centralized-agent-language/tsconfig.json | 9 ++ 12 files changed, 427 insertions(+) create mode 100644 bootstrap-languages/centralized-agent-language/.gitignore create mode 100644 bootstrap-languages/centralized-agent-language/ConstructorIcon.svelte create mode 100644 bootstrap-languages/centralized-agent-language/Icon.svelte create mode 100644 bootstrap-languages/centralized-agent-language/README.md create mode 100644 bootstrap-languages/centralized-agent-language/adapter.ts create mode 100644 bootstrap-languages/centralized-agent-language/esbuild.ts create mode 100644 bootstrap-languages/centralized-agent-language/expressionUI.ts create mode 100644 bootstrap-languages/centralized-agent-language/index.ts create mode 100644 bootstrap-languages/centralized-agent-language/package.json create mode 100644 bootstrap-languages/centralized-agent-language/rollup.config.expression-ui.js create mode 100644 bootstrap-languages/centralized-agent-language/rollup.config.icons.js create mode 100644 bootstrap-languages/centralized-agent-language/tsconfig.json diff --git a/bootstrap-languages/centralized-agent-language/.gitignore b/bootstrap-languages/centralized-agent-language/.gitignore new file mode 100644 index 000000000..1dd4f64d3 --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/.gitignore @@ -0,0 +1,15 @@ +dist/ +node_modules/ +target/ +.hc +.cargo +*.log +*.dna +build/* +*.js +*.js.map +!*.config.icons.js +!*.config.js +!dna.js +build/dna.js +!*-ui.js \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/ConstructorIcon.svelte b/bootstrap-languages/centralized-agent-language/ConstructorIcon.svelte new file mode 100644 index 000000000..5db1c1cfc --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/ConstructorIcon.svelte @@ -0,0 +1,11 @@ + + + + +
+
+ + \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/Icon.svelte b/bootstrap-languages/centralized-agent-language/Icon.svelte new file mode 100644 index 000000000..bb8154459 --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/Icon.svelte @@ -0,0 +1,83 @@ + + + + +
+ +
+

{did}

+

{firstName} {lastName}

+

{email}

+
+ + {#if emailValidator.validate(email) } + gravatar + {/if} +
+ + + \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/README.md b/bootstrap-languages/centralized-agent-language/README.md new file mode 100644 index 000000000..ff5ed3a8c --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/README.md @@ -0,0 +1,3 @@ +# centrazlied-agent-language + +A ad4m language to store Agent data associated with DID's in a centralized server \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/adapter.ts b/bootstrap-languages/centralized-agent-language/adapter.ts new file mode 100644 index 000000000..f1279211b --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/adapter.ts @@ -0,0 +1,61 @@ +import type { Address, Agent, Expression, PublicSharing, LanguageContext, HolochainLanguageDelegate, ExpressionAdapter, AgentService } from "https://esm.sh/@perspect3vism/ad4m@0.5.0"; +import axiod from "https://deno.land/x/axiod/mod.ts"; + +export default class ExpressionAdapterImpl implements ExpressionAdapter { + #agent: AgentService; + putAdapter: PublicSharing + + constructor(context: LanguageContext) { + this.#agent = context.agent; + this.putAdapter = new Sharing(context) + } + + async get(did: Address): Promise { + console.log("Getting expression with did", did); + + const { expression } = await axiod.get("https://socket.ad4m.dev/agent", { + params: { + did + } + }); + + return expression + }; +} + +class Sharing implements PublicSharing { + #agent: AgentService; + + constructor(context: LanguageContext) { + this.#agent = context.agent; + } + + async createPublic(content: Agent): Promise
{ + + if(!content['did'] || !content['perspective'] || !content['perspective'].links) + throw "Content must be an Agent object" + + const agent = content as Agent + if(agent.did != this.#agent.did) + throw "Can't set Agent Expression for foreign DID - only for self" + + if(!agent.directMessageLanguage) + agent.directMessageLanguage = undefined + + agent.perspective!.links.forEach(link => { + delete link.proof.valid + delete link.proof.invalid + }) + + const expression = this.#agent.createSignedExpression(agent); + + await axiod.post("https://socket.ad4m.dev/agent", { + params: { + did: agent.did, + expression + } + }); + + return agent.did + } +} \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/esbuild.ts b/bootstrap-languages/centralized-agent-language/esbuild.ts new file mode 100644 index 000000000..928afaace --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/esbuild.ts @@ -0,0 +1,22 @@ +import * as esbuild from "https://deno.land/x/esbuild@v0.17.18/mod.js"; +// Import the WASM build on platforms where running subprocesses is not +// permitted, such as Deno Deploy, or when running without `--allow-run`. +// import * as esbuild from "https://deno.land/x/esbuild@v0.17.18/wasm.js"; + +import { denoPlugins } from "https://deno.land/x/esbuild_deno_loader@0.7.0/mod.ts"; + +const result = await esbuild.build({ + plugins: [...denoPlugins()], + entryPoints: ['index.ts'], + outfile: 'build/bundle.js', + bundle: true, + platform: 'node', + target: 'deno1.32.4', + format: 'esm', + globalName: 'centralized.agent.language', + charset: 'ascii', + legalComments: 'inline' +}); +console.log(result.outputFiles); + +esbuild.stop(); \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/expressionUI.ts b/bootstrap-languages/centralized-agent-language/expressionUI.ts new file mode 100644 index 000000000..310d1852c --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/expressionUI.ts @@ -0,0 +1,13 @@ +import type { ExpressionUI } from "@perspect3vism/ad4m"; +import Icon from './build/Icon.js' +import ConstructorIcon from './build/ConstructorIcon.js' + +export class UI implements ExpressionUI { + icon(): string { + return Icon + } + + constructorIcon(): string { + return ConstructorIcon + } +} \ No newline at end of file diff --git a/bootstrap-languages/centralized-agent-language/index.ts b/bootstrap-languages/centralized-agent-language/index.ts new file mode 100644 index 000000000..d6ea47363 --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/index.ts @@ -0,0 +1,34 @@ +import type { Address, Language, LanguageContext, HolochainLanguageDelegate, Interaction } from "https://esm.sh/@perspect3vism/ad4m@0.5.0"; +import ExpressionAdapter from "./adapter.ts"; +import Icon from "./build/Icon.js"; +import ConstructorIcon from "./build/ConstructorIcon.js"; +import { UI } from "./build/expressionUI.js"; + +function iconFor(expression: Address): string { + return Icon as unknown as string; +} + +function constructorIcon(): string { + return ConstructorIcon as unknown as string; +} + +function interactions(expression: Address): Interaction[] { + return []; +} + +//!@ad4m-template-variable +export const name = "centralized-agent-expression-store"; + +export default async function create(context: LanguageContext): Promise { + const expressionAdapter = new ExpressionAdapter(context); + const expressionUI = new UI(); + + return { + name, + expressionAdapter, + iconFor, + constructorIcon, + interactions, + expressionUI, + } as Language; +} diff --git a/bootstrap-languages/centralized-agent-language/package.json b/bootstrap-languages/centralized-agent-language/package.json new file mode 100644 index 000000000..fda91d6bf --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/package.json @@ -0,0 +1,45 @@ +{ + "name": "@perspect3vism/centralized-agent-language", + "version": "0.7.1", + "description": "AD4M Language implementation for Holochain profile DNA", + "main": "index.js", + "scripts": { + "test-disabled": "echo \"No agent language integration tests\"", + "rollup-icons": "rollup -c rollup.config.icons.js", + "rollup-expression-ui": "rollup -c rollup.config.expression-ui.js", + "build": "run-script-os", + "build:linux": "yarn build:common", + "build:macos": "yarn build:common", + "build:windows": "yarn build:common", + "build:common": "yarn rollup-icons && yarn rollup-expression-ui && deno run --allow-all esbuild.ts" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@perspect3vism/ad4m": "*", + "@perspect3vism/rollup-plugin-dna": "^0.0.2", + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-node-resolve": "^8.0.0", + "@rollup/plugin-typescript": "^11.1.0", + "@tsconfig/svelte": "^1.0.0", + "@types/node": "^18.0.0", + "rollup": "^2.3.4", + "rollup-plugin-postcss": "^4.0.0", + "rollup-plugin-string": "^3.0.0", + "rollup-plugin-svelte": "^6.0.0", + "rollup-plugin-terser": "^7.0.0", + "run-script-os": "^1.1.6", + "svelte": "^3.0.0", + "svelte-check": "^1.0.0", + "svelte-preprocess": "^4.0.0", + "tslib": "^2.0.0", + "typescript": "^4.2.4", + "xmlhttprequest": "^1.8.0" + }, + "dependencies": { + "email-validator": "^2.0.4", + "md5": "^2.3.0", + "postcss": "^8.2.1" + } +} diff --git a/bootstrap-languages/centralized-agent-language/rollup.config.expression-ui.js b/bootstrap-languages/centralized-agent-language/rollup.config.expression-ui.js new file mode 100644 index 000000000..feb747f71 --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/rollup.config.expression-ui.js @@ -0,0 +1,25 @@ +import { string } from "rollup-plugin-string"; +import typescript from '@rollup/plugin-typescript'; + +export default { + input: "expressionUI.ts", + external: [], + output: { + sourcemap: true, + format: "esm", + name: "AgentExpressionUI", + file: "build/expressionUI.js", + interop: "esModule", + globals: {}, + }, + external: [], + plugins: [ + string({ + include: "build/*.js", + }), + typescript({include: "expressionUI.ts"}), + ], + watch: { + clearScreen: false, + }, +}; diff --git a/bootstrap-languages/centralized-agent-language/rollup.config.icons.js b/bootstrap-languages/centralized-agent-language/rollup.config.icons.js new file mode 100644 index 000000000..557135681 --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/rollup.config.icons.js @@ -0,0 +1,106 @@ +import svelte from "rollup-plugin-svelte"; +import resolve from "@rollup/plugin-node-resolve"; +import commonjs from "@rollup/plugin-commonjs"; +import sveltePreprocess from "svelte-preprocess"; +import postcss from "rollup-plugin-postcss"; + +const production = !process.env.ROLLUP_WATCH; + +export default [ + { + input: "ConstructorIcon.svelte", + output: { + sourcemap: true, + format: "esm", + name: "ConstructorIcon", + file: "build/ConstructorIcon.js", + }, + plugins: [ + svelte({ + // enable run-time checks when not in production + dev: !production, + preprocess: sveltePreprocess(), + customElement: true, + }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ["svelte"], + }), + commonjs(), + postcss({ + extract: true, + minimize: true, + use: [ + [ + "sass", + { + includePaths: ["./src/ui/theme", "./node_modules"], + }, + ], + ], + }), + //typescript({ sourceMap: !production }), + + // If we're building for production (npm run build + // instead of npm run dev), minify + //production && terser() + ], + watch: { + clearScreen: false, + }, + }, + { + input: "Icon.svelte", + output: { + sourcemap: true, + format: "es", + name: "Icon", + file: "build/Icon.js", + }, + plugins: [ + svelte({ + // enable run-time checks when not in production + dev: !production, + preprocess: sveltePreprocess(), + customElement: true, + }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ["svelte"], + }), + commonjs(), + postcss({ + extract: true, + minimize: true, + use: [ + [ + "sass", + { + includePaths: ["./src/ui/theme", "./node_modules"], + }, + ], + ], + }), + //typescript({ sourceMap: !production }), + + // If we're building for production (npm run build + // instead of npm run dev), minify + //production && terser() + ], + watch: { + clearScreen: false, + }, + }, +]; diff --git a/bootstrap-languages/centralized-agent-language/tsconfig.json b/bootstrap-languages/centralized-agent-language/tsconfig.json new file mode 100644 index 000000000..68e2f4be1 --- /dev/null +++ b/bootstrap-languages/centralized-agent-language/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "types": ["node"], + }, + "include": ["*.ts"], + "exclude": ["node_modules/*", "__sapper__/*", "public/*"], + "allowJs": true + } \ No newline at end of file From bee0ab8c6dfb43652d11aa15cfdb8b5f6739298e Mon Sep 17 00:00:00 2001 From: Joshua Parkin Date: Mon, 4 Dec 2023 13:56:51 +0000 Subject: [PATCH 02/13] add new mainnet seed & update mono repo build process --- cli/seed_proto.json | 2 +- rust-executor/src/mainnet_seed.json | 2 +- turbo.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/seed_proto.json b/cli/seed_proto.json index a67674730..6a6eacf2f 100644 --- a/cli/seed_proto.json +++ b/cli/seed_proto.json @@ -36,7 +36,7 @@ "sourceCodeLink": "https://github.com/perspect3vism/agent-language", "possibleTemplateParams": ["uid", "name", "description"] }, - "resource": "../bootstrap-languages/agent-language/build//bundle.js" + "resource": "../bootstrap-languages/centralized-agent-language/build/bundle.js" }, "directMessageLanguage": { "meta": { diff --git a/rust-executor/src/mainnet_seed.json b/rust-executor/src/mainnet_seed.json index 704b10d9b..95bfb7efa 100644 --- a/rust-executor/src/mainnet_seed.json +++ b/rust-executor/src/mainnet_seed.json @@ -8,7 +8,7 @@ "QmzSYwdeC5L6ZyzwgEEVxKPm17UKwPttyXnmNHakjm3EweWq52W" ], "directMessageLanguage": "QmzSYwdp8xNu5UdWWsKQhzZs4JLYDBTk22T7ksoi3hhpscZAm3E", - "agentLanguage": "QmzSYwdigpRrQTmtXcATD4zAFp1nqbXB1tVJT7ho1JaThaXCynL", + "agentLanguage": "QmzSYwdfNPW9kL64nqo8TXBE2H4cm6s3YXcXkPJaiz18RkiDT9j", "perspectiveLanguage": "QmzSYwdeBLCn99QU7DSnJuTFrp7TQGRZkrTDRXvxiv2XAbUFeEx", "neighbourhoodLanguage": "QmzSYwdo2a6E4XghRHrN5eCReyYRDeRE8VnRbvqgoWZsr9B4pxV", "languageLanguageBundle": "// https://deno.land/x/url_join@1.0.0/mod.ts\nvar urlJoin = function(...args) {\n let input;\n if (typeof args[0] === \"object\") {\n input = args[0];\n } else {\n input = [].slice.call(args);\n }\n return normalize(input);\n};\nvar normalize = (strArray) => {\n const resultArray = [];\n if (strArray.length === 0) {\n return \"\";\n }\n if (typeof strArray[0] !== \"string\") {\n throw new TypeError(\"Url must be a string. Received \" + strArray[0]);\n }\n if (strArray[0].match(/^[^/:]+:\\/*$/) && strArray.length > 1) {\n const first = strArray.shift();\n strArray[0] = first + strArray[0];\n }\n if (strArray[0].match(/^file:\\/\\/\\//)) {\n strArray[0] = strArray[0].replace(/^([^/:]+):\\/*/, \"$1:///\");\n } else {\n strArray[0] = strArray[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n }\n for (let i = 0; i < strArray.length; i++) {\n let component = strArray[i];\n if (typeof component !== \"string\") {\n throw new TypeError(\"Url must be a string. Received \" + component);\n }\n if (component === \"\") {\n continue;\n }\n if (i > 0) {\n component = component.replace(/^[\\/]+/, \"\");\n }\n if (i < strArray.length - 1) {\n component = component.replace(/[\\/]+$/, \"\");\n } else {\n component = component.replace(/[\\/]+$/, \"/\");\n }\n resultArray.push(component);\n }\n let str = resultArray.join(\"/\");\n str = str.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n let parts = str.split(\"?\");\n str = parts.shift() + (parts.length > 0 ? \"?\" : \"\") + parts.join(\"&\");\n return str;\n};\n\n// https://deno.land/x/axiod@0.26.2/helpers.ts\nvar methods = [\n \"get\",\n \"post\",\n \"put\",\n \"delete\",\n \"options\",\n \"head\",\n \"connect\",\n \"trace\",\n \"patch\"\n];\nvar addInterceptor = () => {\n const interceptor = {\n list: [],\n use: function(fulfilled, rejected) {\n const id = this.list.length;\n this.list.push({\n fulfilled,\n rejected\n });\n return id;\n },\n eject: function(index) {\n if (this.list[index]) {\n this.list[index] = null;\n }\n }\n };\n return interceptor;\n};\n\n// https://deno.land/x/axiod@0.26.2/mod.ts\nfunction axiod(url, config) {\n if (typeof url === \"string\") {\n return axiod.request(Object.assign({}, axiod.defaults, { url }, config));\n }\n return axiod.request(Object.assign({}, axiod.defaults, url));\n}\naxiod.defaults = {\n url: \"/\",\n method: \"get\",\n timeout: 0,\n withCredentials: false,\n validateStatus: (status) => {\n return status >= 200 && status < 300;\n }\n};\naxiod.create = (config) => {\n const instance = axiod.bind({});\n instance.defaults = Object.assign({}, axiod.defaults, config);\n instance._request = request;\n instance.request = (options) => {\n return instance._request(Object.assign({}, instance.defaults, options));\n };\n instance.get = (url, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"get\" })\n );\n };\n instance.post = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"post\", data })\n );\n };\n instance.put = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"put\", data })\n );\n };\n instance.delete = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"delete\", data })\n );\n };\n instance.options = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"options\", data })\n );\n };\n instance.head = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"head\", data })\n );\n };\n instance.connect = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"connect\", data })\n );\n };\n instance.trace = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"trace\", data })\n );\n };\n instance.patch = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"patch\", data })\n );\n };\n instance.interceptors = {\n request: addInterceptor(),\n response: addInterceptor()\n };\n instance.interceptors.request.list = [];\n instance.interceptors.response.list = [];\n return instance;\n};\nasync function request(config) {\n if (this.interceptors.request.list.length > 0) {\n for (const interceptor of this.interceptors.request.list) {\n if (interceptor) {\n const { fulfilled } = interceptor;\n if (fulfilled && config) {\n config = await fulfilled(config);\n }\n }\n }\n }\n let {\n url = \"/\",\n baseURL,\n method,\n headers,\n params = {},\n data,\n timeout,\n withCredentials,\n auth,\n validateStatus,\n paramsSerializer,\n transformRequest,\n transformResponse,\n redirect,\n responseType = \"json\"\n } = config;\n if (baseURL) {\n url = urlJoin(baseURL, url);\n }\n if (method) {\n if (methods.indexOf(method.toLowerCase().trim()) === -1) {\n throw new Error(`Method ${method} is not supported`);\n } else {\n method = method.toLowerCase().trim();\n }\n } else {\n method = \"get\";\n }\n let _params = \"\";\n if (params) {\n if (paramsSerializer) {\n _params = paramsSerializer(params);\n } else {\n _params = Object.keys(params).map((key) => {\n return encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]);\n }).join(\"&\");\n }\n }\n if (withCredentials) {\n if (auth?.username && auth?.password) {\n if (!headers) {\n headers = {};\n }\n headers[\"Authorization\"] = \"Basic \" + btoa(unescape(encodeURIComponent(`${auth.username}:${auth.password}`)));\n }\n }\n const fetchRequestObject = {};\n if (method !== \"get\") {\n fetchRequestObject.method = method.toUpperCase();\n }\n if (_params) {\n url = urlJoin(url, `?${_params}`);\n }\n if (data && method !== \"get\") {\n if (transformRequest && Array.isArray(transformRequest) && transformRequest.length > 0) {\n for (var i = 0; i < (transformRequest || []).length; i++) {\n if (transformRequest && transformRequest[i]) {\n data = transformRequest[i](data, headers);\n }\n }\n }\n if (typeof data === \"string\" || data instanceof FormData || data instanceof URLSearchParams) {\n fetchRequestObject.body = data;\n } else {\n try {\n fetchRequestObject.body = JSON.stringify(data);\n if (!headers) {\n headers = {};\n }\n headers[\"Accept\"] = \"application/json\";\n headers[\"Content-Type\"] = \"application/json\";\n } catch (ex) {\n }\n }\n }\n if (headers) {\n const _headers = new Headers();\n Object.keys(headers).forEach((header) => {\n if (headers && headers[header]) {\n _headers.set(header, headers[header]);\n }\n });\n fetchRequestObject.headers = _headers;\n }\n const controller = new AbortController();\n fetchRequestObject.signal = controller.signal;\n let timeoutCounter = 0;\n if ((timeout || 0) > 0) {\n timeoutCounter = setTimeout(() => {\n timeoutCounter = 0;\n controller.abort();\n }, timeout);\n }\n if (redirect) {\n fetchRequestObject.redirect = redirect;\n }\n return fetch(url, fetchRequestObject).then(async (x) => {\n if (timeoutCounter) {\n clearTimeout(timeoutCounter);\n }\n const _status = x.status;\n const _statusText = x.statusText;\n let _data = null;\n try {\n const response2 = x.clone();\n if (responseType === \"json\") {\n _data = await response2.json();\n } else if (responseType === \"text\") {\n _data = await response2.text();\n } else if (responseType === \"arraybuffer\") {\n _data = await response2.arrayBuffer();\n } else if (responseType === \"blob\") {\n _data = await response2.blob();\n } else if (responseType === \"stream\") {\n _data = (await response2.blob()).stream();\n } else {\n _data = await response2.text();\n }\n } catch (ex) {\n _data = await x.clone().text();\n }\n if (transformResponse) {\n if (transformResponse && Array.isArray(transformResponse) && transformResponse.length > 0) {\n for (var i2 = 0; i2 < (transformResponse || []).length; i2++) {\n if (transformResponse && transformResponse[i2]) {\n _data = transformResponse[i2](_data);\n }\n }\n }\n }\n const _headers = x.headers;\n const _config = {\n url,\n baseURL,\n method,\n headers,\n params,\n data,\n timeout,\n withCredentials,\n auth,\n paramsSerializer,\n redirect,\n responseType\n };\n let isValidStatus = true;\n if (validateStatus) {\n isValidStatus = validateStatus(_status);\n } else {\n isValidStatus = _status >= 200 && _status <= 303;\n }\n let response = null;\n let error = null;\n if (isValidStatus) {\n response = {\n status: _status,\n statusText: _statusText,\n data: _data,\n headers: _headers,\n config: _config\n };\n } else {\n error = {\n response: {\n status: _status,\n statusText: _statusText,\n data: _data,\n headers: _headers\n },\n config: _config\n };\n }\n if (this.interceptors.response.list.length > 0) {\n for (const interceptor of this.interceptors.response.list) {\n if (interceptor) {\n const { fulfilled, rejected } = interceptor;\n if (fulfilled && response) {\n response = await fulfilled(response);\n }\n if (rejected && error) {\n error = await rejected(error);\n }\n }\n }\n }\n if (error) {\n return Promise.reject(error);\n }\n return Promise.resolve(response);\n });\n}\naxiod._request = request;\naxiod.request = request;\naxiod.get = (url, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"get\" })\n );\n};\naxiod.post = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"post\", data })\n );\n};\naxiod.put = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"put\", data })\n );\n};\naxiod.delete = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"delete\", data })\n );\n};\naxiod.options = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"options\", data })\n );\n};\naxiod.head = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"head\", data })\n );\n};\naxiod.connect = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"connect\", data })\n );\n};\naxiod.trace = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"trace\", data })\n );\n};\naxiod.patch = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"patch\", data })\n );\n};\naxiod.interceptors = {\n request: addInterceptor(),\n response: addInterceptor()\n};\nvar mod_default = axiod;\n\n// languageAdapter.ts\nvar LangAdapter = class {\n constructor(context) {\n }\n async getLanguageSource(address) {\n if (address.substring(0, 2) != \"Qm\") {\n console.error(\"LanguageLanguage.getLanguageSource(): The address is not a valid hash\");\n return \"\";\n }\n const cid = address.toString();\n let presignedUrl;\n try {\n const getPresignedUrl = await mod_default.get(PROXY_URL + `?key=${cid}`);\n presignedUrl = getPresignedUrl.data.url;\n } catch (e) {\n console.error(\"Get language source failed at getting presigned url\", address);\n throw e;\n }\n let languageSource;\n try {\n const getLanguageSource = await mod_default.get(presignedUrl);\n languageSource = getLanguageSource.data;\n } catch (e) {\n console.error(\"Get language source failed at getting language source\", address);\n throw e;\n }\n return languageSource;\n }\n};\n\n// putAdapter.ts\nvar CloudflarePutAdapter = class {\n #agent;\n constructor(context) {\n this.#agent = context.agent;\n }\n async createPublic(language) {\n const hash = UTILS.hash(language.bundle.toString());\n if (hash != language.meta.address)\n throw new Error(`Language Persistence: Can't store language. Address stated in meta differs from actual file\nWanted: ${language.meta.address}\nGot: ${hash}`);\n const agent = this.#agent;\n const expression = agent.createSignedExpression(language.meta);\n const key = `meta-${hash}`;\n const metaPostData = {\n key,\n // Content of the new object.\n value: JSON.stringify(expression)\n };\n try {\n const metaPostResult = await mod_default.post(PROXY_URL, metaPostData);\n if (metaPostResult.status != 200) {\n console.error(\"Upload language meta data gets error: \", metaPostResult);\n }\n const languageBundleBucketParams = {\n key: hash,\n // Content of the new object.\n value: language.bundle.toString()\n };\n const bundlePostResult = await mod_default.post(PROXY_URL, languageBundleBucketParams);\n if (bundlePostResult.status != 200) {\n console.error(\"Upload language bundle data gets error: \", metaPostResult);\n }\n return hash;\n } catch (e) {\n if (e.response.status == 400 && e.response.data.includes(\"Key already exists\")) {\n console.log(\"[Cloudflare-based Language Language]: Tried to replace existing language. Ignoring...\");\n return hash;\n }\n console.error(\"[Cloudflare-based Language Language]: Error storing Language: \", e.response.data);\n throw e;\n }\n }\n};\n\n// adapter.ts\nvar Adapter = class {\n constructor(context) {\n this.putAdapter = new CloudflarePutAdapter(context);\n }\n async get(address) {\n if (address.substring(0, 2) != \"Qm\") {\n console.error(\"LanguageLanguage.get(): The address is not a valid hash\");\n return null;\n }\n const metaDataKey = `meta-${address}`;\n let presignedUrl;\n try {\n const getPresignedUrl = await mod_default.get(PROXY_URL + `?key=${metaDataKey}`);\n presignedUrl = getPresignedUrl.data.url;\n } catch (e) {\n console.error(\"Get meta information failed at getting presigned url\", address);\n return null;\n }\n let metaObject;\n try {\n const getMetaObject = await mod_default.get(presignedUrl);\n metaObject = getMetaObject.data;\n } catch (e) {\n console.error(\"Get meta information failed at getting meta information\", presignedUrl);\n return null;\n }\n return metaObject;\n }\n};\n\n// index.ts\nvar name = \"languages\";\nvar PROXY_URL = \"https://bootstrap-store-gateway.perspect3vism.workers.dev\";\nfunction interactions(expression) {\n return [];\n}\nasync function create(context) {\n const expressionAdapter = new Adapter(context);\n const languageAdapter = new LangAdapter(context);\n return {\n name,\n expressionAdapter,\n languageAdapter,\n interactions\n };\n}\nexport {\n PROXY_URL,\n create as default,\n name\n};\n" diff --git a/turbo.json b/turbo.json index 32382466d..e93c05816 100644 --- a/turbo.json +++ b/turbo.json @@ -14,7 +14,7 @@ "@perspect3vism/direct-message-language#build", "@perspect3vism/perspective-language#build", "@perspect3vism/language-language#build", "@perspect3vism/neighbourhood-language#build", "@perspect3vism/file-storage#build", "@perspect3vism/perspective-diff-sync-socket-signaling#build", - "@perspect3vism/centralized-perspective-diff-sync#build"], + "@perspect3vism/centralized-perspective-diff-sync#build", "@perspect3vism/centralized-agent-language#build"], "outputs": ["dist/**", "lib/**", "build/**"] }, From 840b92779501f52b8456de41f3fd8b60f63b345f Mon Sep 17 00:00:00 2001 From: Fayeed Pawaskar Date: Tue, 5 Dec 2023 11:15:50 +0530 Subject: [PATCH 03/13] Fixed agent language params --- bootstrap-languages/centralized-agent-language/adapter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bootstrap-languages/centralized-agent-language/adapter.ts b/bootstrap-languages/centralized-agent-language/adapter.ts index f1279211b..3b6b18c72 100644 --- a/bootstrap-languages/centralized-agent-language/adapter.ts +++ b/bootstrap-languages/centralized-agent-language/adapter.ts @@ -13,13 +13,13 @@ export default class ExpressionAdapterImpl implements ExpressionAdapter { async get(did: Address): Promise { console.log("Getting expression with did", did); - const { expression } = await axiod.get("https://socket.ad4m.dev/agent", { + const data = await axiod.get("http://localhost:3000/agent", { params: { did } }); - return expression + return data.data.expression }; } @@ -49,8 +49,8 @@ class Sharing implements PublicSharing { const expression = this.#agent.createSignedExpression(agent); - await axiod.post("https://socket.ad4m.dev/agent", { - params: { + await axiod.post("http://localhost:3000/agent", { + data: { did: agent.did, expression } From 4e9d19afd380a105dcd0e4ce14ae078e16dad32f Mon Sep 17 00:00:00 2001 From: Fayeed Pawaskar Date: Tue, 5 Dec 2023 13:24:25 +0530 Subject: [PATCH 04/13] Added centralized file storage language --- .../centralized-file-storage/.gitignore | 12 +++ .../centralized-file-storage/adapter.ts | 95 +++++++++++++++++++ .../centralized-file-storage/esbuild.ts | 22 +++++ .../centralized-file-storage/index.ts | 30 ++++++ .../centralized-file-storage/package.json | 12 +++ .../centralized-file-storage/tsconfig.json | 28 ++++++ 6 files changed, 199 insertions(+) create mode 100644 bootstrap-languages/centralized-file-storage/.gitignore create mode 100644 bootstrap-languages/centralized-file-storage/adapter.ts create mode 100644 bootstrap-languages/centralized-file-storage/esbuild.ts create mode 100644 bootstrap-languages/centralized-file-storage/index.ts create mode 100644 bootstrap-languages/centralized-file-storage/package.json create mode 100644 bootstrap-languages/centralized-file-storage/tsconfig.json diff --git a/bootstrap-languages/centralized-file-storage/.gitignore b/bootstrap-languages/centralized-file-storage/.gitignore new file mode 100644 index 000000000..b99cc4259 --- /dev/null +++ b/bootstrap-languages/centralized-file-storage/.gitignore @@ -0,0 +1,12 @@ +*.dna +hc-dna/zomes/tests/node_modules +hc-dna/.cargo +hc-dna/target +build/* + +*.js +*.js.map +!rollup.config.js +!dna.js + +node_modules \ No newline at end of file diff --git a/bootstrap-languages/centralized-file-storage/adapter.ts b/bootstrap-languages/centralized-file-storage/adapter.ts new file mode 100644 index 000000000..4832f76a9 --- /dev/null +++ b/bootstrap-languages/centralized-file-storage/adapter.ts @@ -0,0 +1,95 @@ +import type { Address, Expression, ExpressionAdapter, PublicSharing, LanguageContext, AgentService } from "https://esm.sh/@perspect3vism/ad4m@0.5.0"; +import axiod from "https://deno.land/x/axiod/mod.ts"; +import { PROXY_URL } from "./index.ts"; +import { ExpressionGeneric } from "https://esm.sh/@perspect3vism/ad4m@0.5.0"; + +export interface FileData { + name: string; + file_type: string; + data_base64: string; +} + +export class FileMetadata { + name: string = ""; + size: number = 0; + file_type: string = ""; +} + +export class FileExpression extends ExpressionGeneric(FileMetadata) {}; + +class PutAdapter implements PublicSharing { + #agent: AgentService; + + constructor(context: LanguageContext) { + this.#agent = context.agent; + } + + async createPublic(fileData: FileData): Promise
{ + console.log("createPublic fileData", fileData) + try { + // Just in case... + if(typeof fileData === "string"){ + //@ts-ignore + fileData = JSON.parse(fileData) + } + }catch(e){} + + const data_uncompressed = Uint8Array.from(Buffer.from(fileData.data_base64, "base64")); + + const fileMetadata = { + name: fileData.name, + size: data_uncompressed.length, + file_type: fileData.file_type, + data_base64: fileData.data_base64 + } as FileMetadata + + // @ts-ignore + const hash = UTILS.hash(JSON.stringify(fileMetadata)); + //Create the signed expression object + const expression: FileExpression = this.#agent.createSignedExpression(fileMetadata) + + const key = hash; + const postData = { + key: key, + value: JSON.stringify(expression), + }; + const postResult = await axiod.post(PROXY_URL, postData); + if (postResult.status != 200) { + console.error("Upload file data gets error: ", postResult); + } + + return hash as Address; + } +} + +export default class Adapter implements ExpressionAdapter { + putAdapter: PublicSharing; + + constructor(context: LanguageContext) { + this.putAdapter = new PutAdapter(context); + } + + async get(address: Address): Promise { + const cid = address.toString(); + + let presignedUrl; + try { + const getPresignedUrl = await axiod.get(PROXY_URL+`?key=${cid}`); + presignedUrl = getPresignedUrl.data.url; + } catch (e) { + console.error("Get File failed at getting presigned url", e); + } + + let object; + try { + const getObject = await axiod.get(presignedUrl); + + object = getObject.data; + } catch (e) { + console.error("Get meta information failed at getting meta information", e); + } + + return object; + } +} + diff --git a/bootstrap-languages/centralized-file-storage/esbuild.ts b/bootstrap-languages/centralized-file-storage/esbuild.ts new file mode 100644 index 000000000..931eb849c --- /dev/null +++ b/bootstrap-languages/centralized-file-storage/esbuild.ts @@ -0,0 +1,22 @@ +import * as esbuild from "https://deno.land/x/esbuild@v0.17.18/mod.js"; +// Import the WASM build on platforms where running subprocesses is not +// permitted, such as Deno Deploy, or when running without `--allow-run`. +// import * as esbuild from "https://deno.land/x/esbuild@v0.17.18/wasm.js"; + +import { denoPlugins } from "https://deno.land/x/esbuild_deno_loader@0.7.0/mod.ts"; + +const result = await esbuild.build({ + plugins: [...denoPlugins()], + entryPoints: ['index.ts'], + outfile: 'build/bundle.js', + bundle: true, + platform: 'node', + target: 'deno1.32.4', + format: 'esm', + globalName: 'centralized.file.storage', + charset: 'ascii', + legalComments: 'inline' +}); +console.log(result.outputFiles); + +esbuild.stop(); \ No newline at end of file diff --git a/bootstrap-languages/centralized-file-storage/index.ts b/bootstrap-languages/centralized-file-storage/index.ts new file mode 100644 index 000000000..5984b80f4 --- /dev/null +++ b/bootstrap-languages/centralized-file-storage/index.ts @@ -0,0 +1,30 @@ +import type { Address, Language, LanguageContext, ExpressionUI, Interaction } from "https://esm.sh/@perspect3vism/ad4m@0.5.0"; +import Adapter from "./adapter.ts"; + +function interactions(expression: Address): Interaction[] { + return []; +} + +export class UI implements ExpressionUI { + icon(): string { + return ""; + } + + constructorIcon(): string { + return ""; + } +} + +export const name = "centralized-file-store"; + +export const PROXY_URL = "https://bootstrap-store-gateway.perspect3vism.workers.dev/"; + +export default async function create(context: LanguageContext): Promise { + const expressionAdapter = new Adapter(context); + + return { + name, + expressionAdapter, + interactions, + } as Language; +} diff --git a/bootstrap-languages/centralized-file-storage/package.json b/bootstrap-languages/centralized-file-storage/package.json new file mode 100644 index 000000000..c77e613a1 --- /dev/null +++ b/bootstrap-languages/centralized-file-storage/package.json @@ -0,0 +1,12 @@ +{ + "name": "@perspect3vism/centralized-file-storage", + "version": "0.7.1", + "description": "This is a Language for storing AD4M file objects", + "main": "index.js", + "scripts": { + "test-disabled": "echo \"No file language integration tests\"", + "build": "deno run --allow-all esbuild.ts" + }, + "author": "joshuadparkin@gmail.com", + "license": "ISC" +} diff --git a/bootstrap-languages/centralized-file-storage/tsconfig.json b/bootstrap-languages/centralized-file-storage/tsconfig.json new file mode 100644 index 000000000..cfbc9c197 --- /dev/null +++ b/bootstrap-languages/centralized-file-storage/tsconfig.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Svelte", + "compilerOptions": { + "moduleResolution": "node", + "target": "es2017", + /** + Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript + to enforce using `import type` instead of `import` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + /** + To have warnings/errors of the Svelte compiler at the correct position, + enable source maps by default. + */ + "sourceMap": true, + /** Requests the runtime types from the svelte modules by default. Needed for TS files or else you get errors. */ + "types": ["svelte", "node"], + + "strict": false, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["*.ts"], + "exclude": ["node_modules/*", "__sapper__/*", "public/*"], +} \ No newline at end of file From 3d62a1429f6835563336a1b1c16bc8dd3116491b Mon Sep 17 00:00:00 2001 From: Joshua Parkin Date: Tue, 5 Dec 2023 11:41:28 +0000 Subject: [PATCH 05/13] add new agent language to mainnet seed --- rust-executor/src/mainnet_seed.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-executor/src/mainnet_seed.json b/rust-executor/src/mainnet_seed.json index 95bfb7efa..4e809a7ee 100644 --- a/rust-executor/src/mainnet_seed.json +++ b/rust-executor/src/mainnet_seed.json @@ -8,7 +8,7 @@ "QmzSYwdeC5L6ZyzwgEEVxKPm17UKwPttyXnmNHakjm3EweWq52W" ], "directMessageLanguage": "QmzSYwdp8xNu5UdWWsKQhzZs4JLYDBTk22T7ksoi3hhpscZAm3E", - "agentLanguage": "QmzSYwdfNPW9kL64nqo8TXBE2H4cm6s3YXcXkPJaiz18RkiDT9j", + "agentLanguage": "QmzSYwdZD6dbSjYKNTjwpDdfXCtKfLhUDiDsjKkeV7Lsqwo1tGn", "perspectiveLanguage": "QmzSYwdeBLCn99QU7DSnJuTFrp7TQGRZkrTDRXvxiv2XAbUFeEx", "neighbourhoodLanguage": "QmzSYwdo2a6E4XghRHrN5eCReyYRDeRE8VnRbvqgoWZsr9B4pxV", "languageLanguageBundle": "// https://deno.land/x/url_join@1.0.0/mod.ts\nvar urlJoin = function(...args) {\n let input;\n if (typeof args[0] === \"object\") {\n input = args[0];\n } else {\n input = [].slice.call(args);\n }\n return normalize(input);\n};\nvar normalize = (strArray) => {\n const resultArray = [];\n if (strArray.length === 0) {\n return \"\";\n }\n if (typeof strArray[0] !== \"string\") {\n throw new TypeError(\"Url must be a string. Received \" + strArray[0]);\n }\n if (strArray[0].match(/^[^/:]+:\\/*$/) && strArray.length > 1) {\n const first = strArray.shift();\n strArray[0] = first + strArray[0];\n }\n if (strArray[0].match(/^file:\\/\\/\\//)) {\n strArray[0] = strArray[0].replace(/^([^/:]+):\\/*/, \"$1:///\");\n } else {\n strArray[0] = strArray[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n }\n for (let i = 0; i < strArray.length; i++) {\n let component = strArray[i];\n if (typeof component !== \"string\") {\n throw new TypeError(\"Url must be a string. Received \" + component);\n }\n if (component === \"\") {\n continue;\n }\n if (i > 0) {\n component = component.replace(/^[\\/]+/, \"\");\n }\n if (i < strArray.length - 1) {\n component = component.replace(/[\\/]+$/, \"\");\n } else {\n component = component.replace(/[\\/]+$/, \"/\");\n }\n resultArray.push(component);\n }\n let str = resultArray.join(\"/\");\n str = str.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n let parts = str.split(\"?\");\n str = parts.shift() + (parts.length > 0 ? \"?\" : \"\") + parts.join(\"&\");\n return str;\n};\n\n// https://deno.land/x/axiod@0.26.2/helpers.ts\nvar methods = [\n \"get\",\n \"post\",\n \"put\",\n \"delete\",\n \"options\",\n \"head\",\n \"connect\",\n \"trace\",\n \"patch\"\n];\nvar addInterceptor = () => {\n const interceptor = {\n list: [],\n use: function(fulfilled, rejected) {\n const id = this.list.length;\n this.list.push({\n fulfilled,\n rejected\n });\n return id;\n },\n eject: function(index) {\n if (this.list[index]) {\n this.list[index] = null;\n }\n }\n };\n return interceptor;\n};\n\n// https://deno.land/x/axiod@0.26.2/mod.ts\nfunction axiod(url, config) {\n if (typeof url === \"string\") {\n return axiod.request(Object.assign({}, axiod.defaults, { url }, config));\n }\n return axiod.request(Object.assign({}, axiod.defaults, url));\n}\naxiod.defaults = {\n url: \"/\",\n method: \"get\",\n timeout: 0,\n withCredentials: false,\n validateStatus: (status) => {\n return status >= 200 && status < 300;\n }\n};\naxiod.create = (config) => {\n const instance = axiod.bind({});\n instance.defaults = Object.assign({}, axiod.defaults, config);\n instance._request = request;\n instance.request = (options) => {\n return instance._request(Object.assign({}, instance.defaults, options));\n };\n instance.get = (url, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"get\" })\n );\n };\n instance.post = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"post\", data })\n );\n };\n instance.put = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"put\", data })\n );\n };\n instance.delete = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"delete\", data })\n );\n };\n instance.options = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"options\", data })\n );\n };\n instance.head = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"head\", data })\n );\n };\n instance.connect = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"connect\", data })\n );\n };\n instance.trace = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"trace\", data })\n );\n };\n instance.patch = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"patch\", data })\n );\n };\n instance.interceptors = {\n request: addInterceptor(),\n response: addInterceptor()\n };\n instance.interceptors.request.list = [];\n instance.interceptors.response.list = [];\n return instance;\n};\nasync function request(config) {\n if (this.interceptors.request.list.length > 0) {\n for (const interceptor of this.interceptors.request.list) {\n if (interceptor) {\n const { fulfilled } = interceptor;\n if (fulfilled && config) {\n config = await fulfilled(config);\n }\n }\n }\n }\n let {\n url = \"/\",\n baseURL,\n method,\n headers,\n params = {},\n data,\n timeout,\n withCredentials,\n auth,\n validateStatus,\n paramsSerializer,\n transformRequest,\n transformResponse,\n redirect,\n responseType = \"json\"\n } = config;\n if (baseURL) {\n url = urlJoin(baseURL, url);\n }\n if (method) {\n if (methods.indexOf(method.toLowerCase().trim()) === -1) {\n throw new Error(`Method ${method} is not supported`);\n } else {\n method = method.toLowerCase().trim();\n }\n } else {\n method = \"get\";\n }\n let _params = \"\";\n if (params) {\n if (paramsSerializer) {\n _params = paramsSerializer(params);\n } else {\n _params = Object.keys(params).map((key) => {\n return encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]);\n }).join(\"&\");\n }\n }\n if (withCredentials) {\n if (auth?.username && auth?.password) {\n if (!headers) {\n headers = {};\n }\n headers[\"Authorization\"] = \"Basic \" + btoa(unescape(encodeURIComponent(`${auth.username}:${auth.password}`)));\n }\n }\n const fetchRequestObject = {};\n if (method !== \"get\") {\n fetchRequestObject.method = method.toUpperCase();\n }\n if (_params) {\n url = urlJoin(url, `?${_params}`);\n }\n if (data && method !== \"get\") {\n if (transformRequest && Array.isArray(transformRequest) && transformRequest.length > 0) {\n for (var i = 0; i < (transformRequest || []).length; i++) {\n if (transformRequest && transformRequest[i]) {\n data = transformRequest[i](data, headers);\n }\n }\n }\n if (typeof data === \"string\" || data instanceof FormData || data instanceof URLSearchParams) {\n fetchRequestObject.body = data;\n } else {\n try {\n fetchRequestObject.body = JSON.stringify(data);\n if (!headers) {\n headers = {};\n }\n headers[\"Accept\"] = \"application/json\";\n headers[\"Content-Type\"] = \"application/json\";\n } catch (ex) {\n }\n }\n }\n if (headers) {\n const _headers = new Headers();\n Object.keys(headers).forEach((header) => {\n if (headers && headers[header]) {\n _headers.set(header, headers[header]);\n }\n });\n fetchRequestObject.headers = _headers;\n }\n const controller = new AbortController();\n fetchRequestObject.signal = controller.signal;\n let timeoutCounter = 0;\n if ((timeout || 0) > 0) {\n timeoutCounter = setTimeout(() => {\n timeoutCounter = 0;\n controller.abort();\n }, timeout);\n }\n if (redirect) {\n fetchRequestObject.redirect = redirect;\n }\n return fetch(url, fetchRequestObject).then(async (x) => {\n if (timeoutCounter) {\n clearTimeout(timeoutCounter);\n }\n const _status = x.status;\n const _statusText = x.statusText;\n let _data = null;\n try {\n const response2 = x.clone();\n if (responseType === \"json\") {\n _data = await response2.json();\n } else if (responseType === \"text\") {\n _data = await response2.text();\n } else if (responseType === \"arraybuffer\") {\n _data = await response2.arrayBuffer();\n } else if (responseType === \"blob\") {\n _data = await response2.blob();\n } else if (responseType === \"stream\") {\n _data = (await response2.blob()).stream();\n } else {\n _data = await response2.text();\n }\n } catch (ex) {\n _data = await x.clone().text();\n }\n if (transformResponse) {\n if (transformResponse && Array.isArray(transformResponse) && transformResponse.length > 0) {\n for (var i2 = 0; i2 < (transformResponse || []).length; i2++) {\n if (transformResponse && transformResponse[i2]) {\n _data = transformResponse[i2](_data);\n }\n }\n }\n }\n const _headers = x.headers;\n const _config = {\n url,\n baseURL,\n method,\n headers,\n params,\n data,\n timeout,\n withCredentials,\n auth,\n paramsSerializer,\n redirect,\n responseType\n };\n let isValidStatus = true;\n if (validateStatus) {\n isValidStatus = validateStatus(_status);\n } else {\n isValidStatus = _status >= 200 && _status <= 303;\n }\n let response = null;\n let error = null;\n if (isValidStatus) {\n response = {\n status: _status,\n statusText: _statusText,\n data: _data,\n headers: _headers,\n config: _config\n };\n } else {\n error = {\n response: {\n status: _status,\n statusText: _statusText,\n data: _data,\n headers: _headers\n },\n config: _config\n };\n }\n if (this.interceptors.response.list.length > 0) {\n for (const interceptor of this.interceptors.response.list) {\n if (interceptor) {\n const { fulfilled, rejected } = interceptor;\n if (fulfilled && response) {\n response = await fulfilled(response);\n }\n if (rejected && error) {\n error = await rejected(error);\n }\n }\n }\n }\n if (error) {\n return Promise.reject(error);\n }\n return Promise.resolve(response);\n });\n}\naxiod._request = request;\naxiod.request = request;\naxiod.get = (url, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"get\" })\n );\n};\naxiod.post = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"post\", data })\n );\n};\naxiod.put = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"put\", data })\n );\n};\naxiod.delete = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"delete\", data })\n );\n};\naxiod.options = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"options\", data })\n );\n};\naxiod.head = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"head\", data })\n );\n};\naxiod.connect = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"connect\", data })\n );\n};\naxiod.trace = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"trace\", data })\n );\n};\naxiod.patch = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"patch\", data })\n );\n};\naxiod.interceptors = {\n request: addInterceptor(),\n response: addInterceptor()\n};\nvar mod_default = axiod;\n\n// languageAdapter.ts\nvar LangAdapter = class {\n constructor(context) {\n }\n async getLanguageSource(address) {\n if (address.substring(0, 2) != \"Qm\") {\n console.error(\"LanguageLanguage.getLanguageSource(): The address is not a valid hash\");\n return \"\";\n }\n const cid = address.toString();\n let presignedUrl;\n try {\n const getPresignedUrl = await mod_default.get(PROXY_URL + `?key=${cid}`);\n presignedUrl = getPresignedUrl.data.url;\n } catch (e) {\n console.error(\"Get language source failed at getting presigned url\", address);\n throw e;\n }\n let languageSource;\n try {\n const getLanguageSource = await mod_default.get(presignedUrl);\n languageSource = getLanguageSource.data;\n } catch (e) {\n console.error(\"Get language source failed at getting language source\", address);\n throw e;\n }\n return languageSource;\n }\n};\n\n// putAdapter.ts\nvar CloudflarePutAdapter = class {\n #agent;\n constructor(context) {\n this.#agent = context.agent;\n }\n async createPublic(language) {\n const hash = UTILS.hash(language.bundle.toString());\n if (hash != language.meta.address)\n throw new Error(`Language Persistence: Can't store language. Address stated in meta differs from actual file\nWanted: ${language.meta.address}\nGot: ${hash}`);\n const agent = this.#agent;\n const expression = agent.createSignedExpression(language.meta);\n const key = `meta-${hash}`;\n const metaPostData = {\n key,\n // Content of the new object.\n value: JSON.stringify(expression)\n };\n try {\n const metaPostResult = await mod_default.post(PROXY_URL, metaPostData);\n if (metaPostResult.status != 200) {\n console.error(\"Upload language meta data gets error: \", metaPostResult);\n }\n const languageBundleBucketParams = {\n key: hash,\n // Content of the new object.\n value: language.bundle.toString()\n };\n const bundlePostResult = await mod_default.post(PROXY_URL, languageBundleBucketParams);\n if (bundlePostResult.status != 200) {\n console.error(\"Upload language bundle data gets error: \", metaPostResult);\n }\n return hash;\n } catch (e) {\n if (e.response.status == 400 && e.response.data.includes(\"Key already exists\")) {\n console.log(\"[Cloudflare-based Language Language]: Tried to replace existing language. Ignoring...\");\n return hash;\n }\n console.error(\"[Cloudflare-based Language Language]: Error storing Language: \", e.response.data);\n throw e;\n }\n }\n};\n\n// adapter.ts\nvar Adapter = class {\n constructor(context) {\n this.putAdapter = new CloudflarePutAdapter(context);\n }\n async get(address) {\n if (address.substring(0, 2) != \"Qm\") {\n console.error(\"LanguageLanguage.get(): The address is not a valid hash\");\n return null;\n }\n const metaDataKey = `meta-${address}`;\n let presignedUrl;\n try {\n const getPresignedUrl = await mod_default.get(PROXY_URL + `?key=${metaDataKey}`);\n presignedUrl = getPresignedUrl.data.url;\n } catch (e) {\n console.error(\"Get meta information failed at getting presigned url\", address);\n return null;\n }\n let metaObject;\n try {\n const getMetaObject = await mod_default.get(presignedUrl);\n metaObject = getMetaObject.data;\n } catch (e) {\n console.error(\"Get meta information failed at getting meta information\", presignedUrl);\n return null;\n }\n return metaObject;\n }\n};\n\n// index.ts\nvar name = \"languages\";\nvar PROXY_URL = \"https://bootstrap-store-gateway.perspect3vism.workers.dev\";\nfunction interactions(expression) {\n return [];\n}\nasync function create(context) {\n const expressionAdapter = new Adapter(context);\n const languageAdapter = new LangAdapter(context);\n return {\n name,\n expressionAdapter,\n languageAdapter,\n interactions\n };\n}\nexport {\n PROXY_URL,\n create as default,\n name\n};\n" From ce56676555a0e334ed34cb9388f4a3a8e1479118 Mon Sep 17 00:00:00 2001 From: Joshua Parkin Date: Tue, 5 Dec 2023 20:06:22 +0000 Subject: [PATCH 06/13] use correct url for socket server --- bootstrap-languages/centralized-agent-language/adapter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap-languages/centralized-agent-language/adapter.ts b/bootstrap-languages/centralized-agent-language/adapter.ts index 3b6b18c72..2f059a5eb 100644 --- a/bootstrap-languages/centralized-agent-language/adapter.ts +++ b/bootstrap-languages/centralized-agent-language/adapter.ts @@ -13,7 +13,7 @@ export default class ExpressionAdapterImpl implements ExpressionAdapter { async get(did: Address): Promise { console.log("Getting expression with did", did); - const data = await axiod.get("http://localhost:3000/agent", { + const data = await axiod.get("https://socket.ad4m.dev/agent", { params: { did } @@ -49,7 +49,7 @@ class Sharing implements PublicSharing { const expression = this.#agent.createSignedExpression(agent); - await axiod.post("http://localhost:3000/agent", { + await axiod.post("https://socket.ad4m.dev/agent", { data: { did: agent.did, expression From d92496ce55fdb77cea4c4bb8abf2171959328ddd Mon Sep 17 00:00:00 2001 From: Joshua Parkin Date: Tue, 5 Dec 2023 20:09:41 +0000 Subject: [PATCH 07/13] add new agent language in mainnet --- rust-executor/src/mainnet_seed.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-executor/src/mainnet_seed.json b/rust-executor/src/mainnet_seed.json index 4e809a7ee..939c60284 100644 --- a/rust-executor/src/mainnet_seed.json +++ b/rust-executor/src/mainnet_seed.json @@ -8,7 +8,7 @@ "QmzSYwdeC5L6ZyzwgEEVxKPm17UKwPttyXnmNHakjm3EweWq52W" ], "directMessageLanguage": "QmzSYwdp8xNu5UdWWsKQhzZs4JLYDBTk22T7ksoi3hhpscZAm3E", - "agentLanguage": "QmzSYwdZD6dbSjYKNTjwpDdfXCtKfLhUDiDsjKkeV7Lsqwo1tGn", + "agentLanguage": "QmzSYwdZDdgxiyE8crozqbxoBP52h6ocMdDq2S2mg4ScjzVLWKQ", "perspectiveLanguage": "QmzSYwdeBLCn99QU7DSnJuTFrp7TQGRZkrTDRXvxiv2XAbUFeEx", "neighbourhoodLanguage": "QmzSYwdo2a6E4XghRHrN5eCReyYRDeRE8VnRbvqgoWZsr9B4pxV", "languageLanguageBundle": "// https://deno.land/x/url_join@1.0.0/mod.ts\nvar urlJoin = function(...args) {\n let input;\n if (typeof args[0] === \"object\") {\n input = args[0];\n } else {\n input = [].slice.call(args);\n }\n return normalize(input);\n};\nvar normalize = (strArray) => {\n const resultArray = [];\n if (strArray.length === 0) {\n return \"\";\n }\n if (typeof strArray[0] !== \"string\") {\n throw new TypeError(\"Url must be a string. Received \" + strArray[0]);\n }\n if (strArray[0].match(/^[^/:]+:\\/*$/) && strArray.length > 1) {\n const first = strArray.shift();\n strArray[0] = first + strArray[0];\n }\n if (strArray[0].match(/^file:\\/\\/\\//)) {\n strArray[0] = strArray[0].replace(/^([^/:]+):\\/*/, \"$1:///\");\n } else {\n strArray[0] = strArray[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n }\n for (let i = 0; i < strArray.length; i++) {\n let component = strArray[i];\n if (typeof component !== \"string\") {\n throw new TypeError(\"Url must be a string. Received \" + component);\n }\n if (component === \"\") {\n continue;\n }\n if (i > 0) {\n component = component.replace(/^[\\/]+/, \"\");\n }\n if (i < strArray.length - 1) {\n component = component.replace(/[\\/]+$/, \"\");\n } else {\n component = component.replace(/[\\/]+$/, \"/\");\n }\n resultArray.push(component);\n }\n let str = resultArray.join(\"/\");\n str = str.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n let parts = str.split(\"?\");\n str = parts.shift() + (parts.length > 0 ? \"?\" : \"\") + parts.join(\"&\");\n return str;\n};\n\n// https://deno.land/x/axiod@0.26.2/helpers.ts\nvar methods = [\n \"get\",\n \"post\",\n \"put\",\n \"delete\",\n \"options\",\n \"head\",\n \"connect\",\n \"trace\",\n \"patch\"\n];\nvar addInterceptor = () => {\n const interceptor = {\n list: [],\n use: function(fulfilled, rejected) {\n const id = this.list.length;\n this.list.push({\n fulfilled,\n rejected\n });\n return id;\n },\n eject: function(index) {\n if (this.list[index]) {\n this.list[index] = null;\n }\n }\n };\n return interceptor;\n};\n\n// https://deno.land/x/axiod@0.26.2/mod.ts\nfunction axiod(url, config) {\n if (typeof url === \"string\") {\n return axiod.request(Object.assign({}, axiod.defaults, { url }, config));\n }\n return axiod.request(Object.assign({}, axiod.defaults, url));\n}\naxiod.defaults = {\n url: \"/\",\n method: \"get\",\n timeout: 0,\n withCredentials: false,\n validateStatus: (status) => {\n return status >= 200 && status < 300;\n }\n};\naxiod.create = (config) => {\n const instance = axiod.bind({});\n instance.defaults = Object.assign({}, axiod.defaults, config);\n instance._request = request;\n instance.request = (options) => {\n return instance._request(Object.assign({}, instance.defaults, options));\n };\n instance.get = (url, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"get\" })\n );\n };\n instance.post = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"post\", data })\n );\n };\n instance.put = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"put\", data })\n );\n };\n instance.delete = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"delete\", data })\n );\n };\n instance.options = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"options\", data })\n );\n };\n instance.head = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"head\", data })\n );\n };\n instance.connect = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"connect\", data })\n );\n };\n instance.trace = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"trace\", data })\n );\n };\n instance.patch = (url, data, config2) => {\n return instance.request(\n Object.assign({}, { url }, config2, { method: \"patch\", data })\n );\n };\n instance.interceptors = {\n request: addInterceptor(),\n response: addInterceptor()\n };\n instance.interceptors.request.list = [];\n instance.interceptors.response.list = [];\n return instance;\n};\nasync function request(config) {\n if (this.interceptors.request.list.length > 0) {\n for (const interceptor of this.interceptors.request.list) {\n if (interceptor) {\n const { fulfilled } = interceptor;\n if (fulfilled && config) {\n config = await fulfilled(config);\n }\n }\n }\n }\n let {\n url = \"/\",\n baseURL,\n method,\n headers,\n params = {},\n data,\n timeout,\n withCredentials,\n auth,\n validateStatus,\n paramsSerializer,\n transformRequest,\n transformResponse,\n redirect,\n responseType = \"json\"\n } = config;\n if (baseURL) {\n url = urlJoin(baseURL, url);\n }\n if (method) {\n if (methods.indexOf(method.toLowerCase().trim()) === -1) {\n throw new Error(`Method ${method} is not supported`);\n } else {\n method = method.toLowerCase().trim();\n }\n } else {\n method = \"get\";\n }\n let _params = \"\";\n if (params) {\n if (paramsSerializer) {\n _params = paramsSerializer(params);\n } else {\n _params = Object.keys(params).map((key) => {\n return encodeURIComponent(key) + \"=\" + encodeURIComponent(params[key]);\n }).join(\"&\");\n }\n }\n if (withCredentials) {\n if (auth?.username && auth?.password) {\n if (!headers) {\n headers = {};\n }\n headers[\"Authorization\"] = \"Basic \" + btoa(unescape(encodeURIComponent(`${auth.username}:${auth.password}`)));\n }\n }\n const fetchRequestObject = {};\n if (method !== \"get\") {\n fetchRequestObject.method = method.toUpperCase();\n }\n if (_params) {\n url = urlJoin(url, `?${_params}`);\n }\n if (data && method !== \"get\") {\n if (transformRequest && Array.isArray(transformRequest) && transformRequest.length > 0) {\n for (var i = 0; i < (transformRequest || []).length; i++) {\n if (transformRequest && transformRequest[i]) {\n data = transformRequest[i](data, headers);\n }\n }\n }\n if (typeof data === \"string\" || data instanceof FormData || data instanceof URLSearchParams) {\n fetchRequestObject.body = data;\n } else {\n try {\n fetchRequestObject.body = JSON.stringify(data);\n if (!headers) {\n headers = {};\n }\n headers[\"Accept\"] = \"application/json\";\n headers[\"Content-Type\"] = \"application/json\";\n } catch (ex) {\n }\n }\n }\n if (headers) {\n const _headers = new Headers();\n Object.keys(headers).forEach((header) => {\n if (headers && headers[header]) {\n _headers.set(header, headers[header]);\n }\n });\n fetchRequestObject.headers = _headers;\n }\n const controller = new AbortController();\n fetchRequestObject.signal = controller.signal;\n let timeoutCounter = 0;\n if ((timeout || 0) > 0) {\n timeoutCounter = setTimeout(() => {\n timeoutCounter = 0;\n controller.abort();\n }, timeout);\n }\n if (redirect) {\n fetchRequestObject.redirect = redirect;\n }\n return fetch(url, fetchRequestObject).then(async (x) => {\n if (timeoutCounter) {\n clearTimeout(timeoutCounter);\n }\n const _status = x.status;\n const _statusText = x.statusText;\n let _data = null;\n try {\n const response2 = x.clone();\n if (responseType === \"json\") {\n _data = await response2.json();\n } else if (responseType === \"text\") {\n _data = await response2.text();\n } else if (responseType === \"arraybuffer\") {\n _data = await response2.arrayBuffer();\n } else if (responseType === \"blob\") {\n _data = await response2.blob();\n } else if (responseType === \"stream\") {\n _data = (await response2.blob()).stream();\n } else {\n _data = await response2.text();\n }\n } catch (ex) {\n _data = await x.clone().text();\n }\n if (transformResponse) {\n if (transformResponse && Array.isArray(transformResponse) && transformResponse.length > 0) {\n for (var i2 = 0; i2 < (transformResponse || []).length; i2++) {\n if (transformResponse && transformResponse[i2]) {\n _data = transformResponse[i2](_data);\n }\n }\n }\n }\n const _headers = x.headers;\n const _config = {\n url,\n baseURL,\n method,\n headers,\n params,\n data,\n timeout,\n withCredentials,\n auth,\n paramsSerializer,\n redirect,\n responseType\n };\n let isValidStatus = true;\n if (validateStatus) {\n isValidStatus = validateStatus(_status);\n } else {\n isValidStatus = _status >= 200 && _status <= 303;\n }\n let response = null;\n let error = null;\n if (isValidStatus) {\n response = {\n status: _status,\n statusText: _statusText,\n data: _data,\n headers: _headers,\n config: _config\n };\n } else {\n error = {\n response: {\n status: _status,\n statusText: _statusText,\n data: _data,\n headers: _headers\n },\n config: _config\n };\n }\n if (this.interceptors.response.list.length > 0) {\n for (const interceptor of this.interceptors.response.list) {\n if (interceptor) {\n const { fulfilled, rejected } = interceptor;\n if (fulfilled && response) {\n response = await fulfilled(response);\n }\n if (rejected && error) {\n error = await rejected(error);\n }\n }\n }\n }\n if (error) {\n return Promise.reject(error);\n }\n return Promise.resolve(response);\n });\n}\naxiod._request = request;\naxiod.request = request;\naxiod.get = (url, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"get\" })\n );\n};\naxiod.post = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"post\", data })\n );\n};\naxiod.put = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"put\", data })\n );\n};\naxiod.delete = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"delete\", data })\n );\n};\naxiod.options = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"options\", data })\n );\n};\naxiod.head = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"head\", data })\n );\n};\naxiod.connect = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"connect\", data })\n );\n};\naxiod.trace = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"trace\", data })\n );\n};\naxiod.patch = (url, data, config) => {\n return axiod.request(\n Object.assign({}, { url }, config, { method: \"patch\", data })\n );\n};\naxiod.interceptors = {\n request: addInterceptor(),\n response: addInterceptor()\n};\nvar mod_default = axiod;\n\n// languageAdapter.ts\nvar LangAdapter = class {\n constructor(context) {\n }\n async getLanguageSource(address) {\n if (address.substring(0, 2) != \"Qm\") {\n console.error(\"LanguageLanguage.getLanguageSource(): The address is not a valid hash\");\n return \"\";\n }\n const cid = address.toString();\n let presignedUrl;\n try {\n const getPresignedUrl = await mod_default.get(PROXY_URL + `?key=${cid}`);\n presignedUrl = getPresignedUrl.data.url;\n } catch (e) {\n console.error(\"Get language source failed at getting presigned url\", address);\n throw e;\n }\n let languageSource;\n try {\n const getLanguageSource = await mod_default.get(presignedUrl);\n languageSource = getLanguageSource.data;\n } catch (e) {\n console.error(\"Get language source failed at getting language source\", address);\n throw e;\n }\n return languageSource;\n }\n};\n\n// putAdapter.ts\nvar CloudflarePutAdapter = class {\n #agent;\n constructor(context) {\n this.#agent = context.agent;\n }\n async createPublic(language) {\n const hash = UTILS.hash(language.bundle.toString());\n if (hash != language.meta.address)\n throw new Error(`Language Persistence: Can't store language. Address stated in meta differs from actual file\nWanted: ${language.meta.address}\nGot: ${hash}`);\n const agent = this.#agent;\n const expression = agent.createSignedExpression(language.meta);\n const key = `meta-${hash}`;\n const metaPostData = {\n key,\n // Content of the new object.\n value: JSON.stringify(expression)\n };\n try {\n const metaPostResult = await mod_default.post(PROXY_URL, metaPostData);\n if (metaPostResult.status != 200) {\n console.error(\"Upload language meta data gets error: \", metaPostResult);\n }\n const languageBundleBucketParams = {\n key: hash,\n // Content of the new object.\n value: language.bundle.toString()\n };\n const bundlePostResult = await mod_default.post(PROXY_URL, languageBundleBucketParams);\n if (bundlePostResult.status != 200) {\n console.error(\"Upload language bundle data gets error: \", metaPostResult);\n }\n return hash;\n } catch (e) {\n if (e.response.status == 400 && e.response.data.includes(\"Key already exists\")) {\n console.log(\"[Cloudflare-based Language Language]: Tried to replace existing language. Ignoring...\");\n return hash;\n }\n console.error(\"[Cloudflare-based Language Language]: Error storing Language: \", e.response.data);\n throw e;\n }\n }\n};\n\n// adapter.ts\nvar Adapter = class {\n constructor(context) {\n this.putAdapter = new CloudflarePutAdapter(context);\n }\n async get(address) {\n if (address.substring(0, 2) != \"Qm\") {\n console.error(\"LanguageLanguage.get(): The address is not a valid hash\");\n return null;\n }\n const metaDataKey = `meta-${address}`;\n let presignedUrl;\n try {\n const getPresignedUrl = await mod_default.get(PROXY_URL + `?key=${metaDataKey}`);\n presignedUrl = getPresignedUrl.data.url;\n } catch (e) {\n console.error(\"Get meta information failed at getting presigned url\", address);\n return null;\n }\n let metaObject;\n try {\n const getMetaObject = await mod_default.get(presignedUrl);\n metaObject = getMetaObject.data;\n } catch (e) {\n console.error(\"Get meta information failed at getting meta information\", presignedUrl);\n return null;\n }\n return metaObject;\n }\n};\n\n// index.ts\nvar name = \"languages\";\nvar PROXY_URL = \"https://bootstrap-store-gateway.perspect3vism.workers.dev\";\nfunction interactions(expression) {\n return [];\n}\nasync function create(context) {\n const expressionAdapter = new Adapter(context);\n const languageAdapter = new LangAdapter(context);\n return {\n name,\n expressionAdapter,\n languageAdapter,\n interactions\n };\n}\nexport {\n PROXY_URL,\n create as default,\n name\n};\n" From 53140a8a0f707215a2f67fd889ecc708c7f4a0de Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 7 Dec 2023 18:54:36 +0100 Subject: [PATCH 08/13] pnpm lock update --- pnpm-lock.yaml | 77 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d80aa5b8f..c1133355c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,6 +171,81 @@ importers: specifier: ^1.8.0 version: 1.8.0 + bootstrap-languages/centralized-agent-language: + dependencies: + email-validator: + specifier: ^2.0.4 + version: 2.0.4 + md5: + specifier: ^2.3.0 + version: 2.3.0 + postcss: + specifier: ^8.2.1 + version: 8.4.31 + devDependencies: + '@perspect3vism/ad4m': + specifier: '*' + version: link:../../core + '@perspect3vism/rollup-plugin-dna': + specifier: ^0.0.2 + version: 0.0.2 + '@rollup/plugin-commonjs': + specifier: ^17.0.0 + version: 17.1.0(rollup@2.79.1) + '@rollup/plugin-json': + specifier: ^4.1.0 + version: 4.1.0(rollup@2.79.1) + '@rollup/plugin-node-resolve': + specifier: ^8.0.0 + version: 8.4.0(rollup@2.79.1) + '@rollup/plugin-typescript': + specifier: ^11.1.0 + version: 11.1.5(rollup@2.79.1)(tslib@2.6.2)(typescript@4.9.5) + '@tsconfig/svelte': + specifier: ^1.0.0 + version: 1.0.13 + '@types/node': + specifier: ^18.0.0 + version: 18.11.10 + rollup: + specifier: ^2.3.4 + version: 2.79.1 + rollup-plugin-postcss: + specifier: ^4.0.0 + version: 4.0.2(postcss@8.4.31) + rollup-plugin-string: + specifier: ^3.0.0 + version: 3.0.0 + rollup-plugin-svelte: + specifier: ^6.0.0 + version: 6.1.1(rollup@2.79.1)(svelte@3.59.2) + rollup-plugin-terser: + specifier: ^7.0.0 + version: 7.0.2(rollup@2.79.1) + run-script-os: + specifier: ^1.1.6 + version: 1.1.6 + svelte: + specifier: ^3.0.0 + version: 3.59.2 + svelte-check: + specifier: ^1.0.0 + version: 1.6.0(postcss@8.4.31)(svelte@3.59.2) + svelte-preprocess: + specifier: ^4.0.0 + version: 4.10.7(postcss@8.4.31)(svelte@3.59.2)(typescript@4.9.5) + tslib: + specifier: ^2.0.0 + version: 2.6.2 + typescript: + specifier: ^4.2.4 + version: 4.9.5 + xmlhttprequest: + specifier: ^1.8.0 + version: 1.8.0 + + bootstrap-languages/centralized-file-storage: {} + bootstrap-languages/centralized-p-diff-sync: dependencies: '@perspect3vism/ad4m': @@ -14350,7 +14425,7 @@ packages: requiresBuild: true dependencies: ansi-escapes: 3.2.0 - chalk: 2.1.0 + chalk: 2.4.2 cli-cursor: 2.1.0 cli-width: 2.2.1 external-editor: 2.2.0 From 6337337d606bd7fc95cfbd3de2890888ab560d59 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 7 Dec 2023 18:54:48 +0100 Subject: [PATCH 09/13] Add centralized file storage language to publishAlso --- cli/seed_proto.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cli/seed_proto.json b/cli/seed_proto.json index 85453bbe9..771d3011b 100644 --- a/cli/seed_proto.json +++ b/cli/seed_proto.json @@ -75,6 +75,15 @@ }, "resource": "../bootstrap-languages/file-storage/build/bundle.js" }, + { + "meta": { + "name": "centralizedFileStorageLanguage", + "description": "Cloudflare based language for storing files", + "sourceCodeLink": "https://github.com/coasys/ad4m", + "possibleTemplateParams": ["uid", "name", "description"] + }, + "resource": "../bootstrap-languages/centralized-file-storage/build/bundle.js" + }, { "meta": { "name": "easLanguage", From b83d757cd8b1c98a564872269a9b833fb4136239 Mon Sep 17 00:00:00 2001 From: Fayeed Pawaskar Date: Fri, 8 Dec 2023 16:50:55 +0530 Subject: [PATCH 10/13] used pnpm instead of yarn --- .../centralized-agent-language/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bootstrap-languages/centralized-agent-language/package.json b/bootstrap-languages/centralized-agent-language/package.json index fda91d6bf..99691ea6e 100644 --- a/bootstrap-languages/centralized-agent-language/package.json +++ b/bootstrap-languages/centralized-agent-language/package.json @@ -8,10 +8,10 @@ "rollup-icons": "rollup -c rollup.config.icons.js", "rollup-expression-ui": "rollup -c rollup.config.expression-ui.js", "build": "run-script-os", - "build:linux": "yarn build:common", - "build:macos": "yarn build:common", - "build:windows": "yarn build:common", - "build:common": "yarn rollup-icons && yarn rollup-expression-ui && deno run --allow-all esbuild.ts" + "build:linux": "pnpm run build:common", + "build:macos": "pnpm run build:common", + "build:windows": "pnpm run build:common", + "build:common": "pnpm run rollup-icons && pnpm run rollup-expression-ui && deno run --allow-all esbuild.ts" }, "author": "", "license": "ISC", From 23fe3743d0ebfd85da6f323bbadb2ce113edcb16 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 8 Dec 2023 12:22:15 +0100 Subject: [PATCH 11/13] Add centralized-file-storage language to turbo --- turbo.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/turbo.json b/turbo.json index e810a2b19..7d6325711 100644 --- a/turbo.json +++ b/turbo.json @@ -14,7 +14,8 @@ "@perspect3vism/direct-message-language#build", "@perspect3vism/perspective-language#build", "@perspect3vism/language-language#build", "@perspect3vism/neighbourhood-language#build", "@perspect3vism/file-storage#build", "@perspect3vism/perspective-diff-sync-socket-signaling#build", - "@perspect3vism/centralized-perspective-diff-sync#build", "@perspect3vism/centralized-agent-language#build"], + "@perspect3vism/centralized-perspective-diff-sync#build", "@perspect3vism/centralized-agent-language#build", + "@perspect3vism/centralized-file-storage#build"], "outputs": ["dist/**", "lib/**", "build/**"] }, From dbc27fd48efc600ef0e1c127659df4c88d0cadf8 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 8 Dec 2023 12:25:42 +0100 Subject: [PATCH 12/13] Add EAS language to turbo --- turbo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbo.json b/turbo.json index 7d6325711..ad4cd7dc5 100644 --- a/turbo.json +++ b/turbo.json @@ -15,7 +15,7 @@ "@perspect3vism/language-language#build", "@perspect3vism/neighbourhood-language#build", "@perspect3vism/file-storage#build", "@perspect3vism/perspective-diff-sync-socket-signaling#build", "@perspect3vism/centralized-perspective-diff-sync#build", "@perspect3vism/centralized-agent-language#build", - "@perspect3vism/centralized-file-storage#build"], + "@perspect3vism/centralized-file-storage#build", "@perspect3vism/eas#build"], "outputs": ["dist/**", "lib/**", "build/**"] }, From 1a920f6f5a72f10bc470b960b0abe87bb86990b6 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Fri, 8 Dec 2023 13:06:04 +0100 Subject: [PATCH 13/13] Fix getTelepresenceAdapter() and reactiate TP tests --- executor/src/core/Perspective.ts | 2 +- tests/js/tests/neighbourhood.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/executor/src/core/Perspective.ts b/executor/src/core/Perspective.ts index 4b7eba74c..0b681653a 100644 --- a/executor/src/core/Perspective.ts +++ b/executor/src/core/Perspective.ts @@ -399,7 +399,7 @@ export default class Perspective { if(!this.getLinksAdapter()) { return null; } - const address = this.neighbourhood!.linkLanguage; + const address = this.neighbourhood!.data.linkLanguage; const telepresenceAdapter = await this.#languageController!.getTelepresenceAdapter({address} as LanguageRef); return telepresenceAdapter } diff --git a/tests/js/tests/neighbourhood.ts b/tests/js/tests/neighbourhood.ts index ee7640af6..d34bc4a35 100644 --- a/tests/js/tests/neighbourhood.ts +++ b/tests/js/tests/neighbourhood.ts @@ -201,7 +201,7 @@ export default function neighbourhoodTests(testContext: TestContext) { // }) - describe.skip('with set up and joined NH for Telepresence', async () => { + describe('with set up and joined NH for Telepresence', async () => { let aliceNH: NeighbourhoodProxy|undefined let bobNH: NeighbourhoodProxy|undefined let aliceDID: string|undefined