Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix P-diff-sync #454

Merged
merged 7 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn init(_: ()) -> ExternResult<InitCallbackResult> {
let mut functions = BTreeSet::new();
functions.insert((zome_info()?.name, "get_online_status".into()));
//TODO; is this next function needed?
functions.insert((zome_info()?.name, "recv_send_remote_signal".into()));
functions.insert((zome_info()?.name, "recv_remote_signal".into()));

let functions: GrantedFunctions = GrantedFunctions::Listed(functions);

Expand Down Expand Up @@ -100,10 +100,11 @@ pub fn update_current_revision(_hash: Hash) -> ExternResult<()> {
/// Signal handling

#[hdk_extern]
fn recv_send_remote_signal(signal: SerializedBytes) -> ExternResult<()> {
fn recv_remote_signal(signal: SerializedBytes) -> ExternResult<()> {
//Check if its a normal diff expression signal
match HashBroadcast::try_from(signal.clone()) {
Ok(broadcast) => {
info!("recv_remote_signal broadcast: {:?}", broadcast);
link_adapter::pull::handle_broadcast::<retriever::HolochainRetreiver>(broadcast)
.map_err(|err| utils::err(&format!("{}", err)))?;
}
Expand Down
8 changes: 4 additions & 4 deletions cli/mainnet_seed.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"did:key:z6MkvPpWxwXAnLtMcoc9sX7GEoJ96oNnQ3VcQJRLspNJfpE7"
],
"knownLinkLanguages": [
"QmzSYwddewWW2BbWhreKBaok2LKPAAM6fvWnAov6kGXowEuRHjR",
"QmzSYwddGEumgdAgQGJhMA1uE2DfrnMEnNYMe3dn4kjdGJAmmEk",
"QmzSYwdbfoeiJ1UW1MFdRNSh6txNnNCS5uYqgfJjzJjsu2GRbWx",
"QmzSYwddjYfNpgFk69C1DfWeNc3uPS1rKNJEj5TqouhCcAgzPUx",
"QmzSYwdnHrRH8MmuPWKKrDvFoVyW5CophNpT1ipQUCcenPVTQnd"
],
"directMessageLanguage": "QmzSYwdebMWD8484aQUB1KWLPqQGezbXWfcu1wMQu983e1ZgGG9",
"agentLanguage": "QmzSYwdZDdgxiyE8crozqbxoBP52h6ocMdDq2S2mg4ScjzVLWKQ",
"directMessageLanguage": "QmzSYwdnJwf8hHkdktTj2shuLcM712czTN7Y7LwKXyLa3mFqDvt",
"agentLanguage": "QmzSYwdYZaPyUT5iKuybkt6sfxPVaWXRS7vRwAyurev3XCYfAft",
"perspectiveLanguage": "QmzSYwddxFCzVD63LgR8MTBaUEcwf9jhB3XjLbYBp2q8V1MqVtS",
"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"
Expand Down
4 changes: 2 additions & 2 deletions cli/seed_proto.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
{
"meta": {
"name": "perspectiveDiffSync",
"name": "perspectiveDiffSync-socket",
"description": "Holochain based Perspective link sharing language, with revision signals sent with socket.io through a centralized server",
"sourceCodeLink": "https://github.com/coasys/ad4m/tree/dev/bootstrap-languages/p-diff-sync-socket-signaling",
"possibleTemplateParams": ["uid", "name", "description"]
Expand All @@ -21,7 +21,7 @@
},
{
"meta": {
"name": "perspectiveDiffSync",
"name": "CloudLinks",
"description": "Centralized link language",
"sourceCodeLink": "https://github.com/coasys/ad4m/tree/dev/bootstrap-languages/p-diff-sync-socket-signaling",
"possibleTemplateParams": ["uid", "name", "description"]
Expand Down
Loading