From 61d302cf4c80a9e29c60c493bba13acfd3a89c95 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 01:25:56 +0100 Subject: [PATCH 01/60] move utils from uix --- utils/args.ts | 3 +- utils/format-endpoint-url.ts | 12 + utils/path.ts | 504 +++++++++++++++++++++++++++++++++++ 3 files changed, 518 insertions(+), 1 deletion(-) create mode 100644 utils/format-endpoint-url.ts create mode 100644 utils/path.ts diff --git a/utils/args.ts b/utils/args.ts index c7f51d8d..279fa616 100644 --- a/utils/args.ts +++ b/utils/args.ts @@ -8,4 +8,5 @@ catch { ({CommandLineOptions} = await import("./_command_line_options.ts")); } -export const commandLineOptions = new CommandLineOptions("DATEX Core", "DATEX Runtime for JavaScript/TypeScript.\nVisit https://unyt.org/datex for more information"); \ No newline at end of file +export const commandLineOptions = new CommandLineOptions("DATEX Core", "DATEX Runtime for JavaScript/TypeScript.\nVisit https://unyt.org/datex for more information"); +export const clear = commandLineOptions.option("clear", {type:"boolean", description: "Clear all eternal states on the backend"}); diff --git a/utils/format-endpoint-url.ts b/utils/format-endpoint-url.ts new file mode 100644 index 00000000..cbf7d308 --- /dev/null +++ b/utils/format-endpoint-url.ts @@ -0,0 +1,12 @@ +import { Endpoint, Institution, Person } from "../types/addressing.ts"; + +export function formatEndpointURL(endpoint:Endpoint) { + const domainName = normalizeDomainName(endpoint.name); + if (endpoint instanceof Institution) return `${domainName}.unyt.app` + else if (endpoint instanceof Person) return `${domainName}.unyt.app` // TODO: unyt.me? + else return `${domainName}.unyt.app` +} + +function normalizeDomainName(name: string) { + return name.replaceAll("_", "-"); +} \ No newline at end of file diff --git a/utils/path.ts b/utils/path.ts new file mode 100644 index 00000000..f02578f3 --- /dev/null +++ b/utils/path.ts @@ -0,0 +1,504 @@ +// deno-lint-ignore-file no-namespace +import { client_type } from "./constants.ts"; +import { getCallerFile } from "./caller_metadata.ts"; + +const relative = client_type === "deno" ? (await import("https://deno.land/std@0.172.0/path/mod.ts")).relative : null; + +export class Path

extends URL { + + declare protocol: P + + + constructor(path:Path.representation = "./", base?:string|URL) { + path = Path.#formatPath(path, !base); + if (!base && !Path.pathIsURL(path)) base = getCallerFile() // resolve path relative to caller file + if (typeof base == "string" && base.match(/^\w:(\\|\/)/)) base = 'file:///' + base; + super(path, base); + } + + // convert to dir/ path + static dir

(path?:Path.representation, base?:Path): Path + static dir(path?:Path.representation, base?:string|URL): Path + static dir(path:Path.representation = "./", base?:string|URL) { + path = Path.#formatPath(path, !base); + if (!base && !Path.pathIsURL(path)) base = getCallerFile() // resolve path relative to caller file + + if (!path.toString().endsWith("/")) path = path.toString() + "/"; // make sure its a dir path + return new Path(path, base); + } + + // convert to file/ path + static file

(path?:Path.representation, base?:Path): Path + static file(path?:Path.representation, base?:string|URL): Path + static file(path:Path.representation = "./", base?:string|URL) { + path = Path.#formatPath(path, !base); + if (!base && !Path.pathIsURL(path)) base = getCallerFile() // resolve path relative to caller file + + if (path.toString().endsWith("/")) path = path.toString().slice(0, -1); // make sure its a file path + return new Path(path, base); + } + + // get path for current working directory + static cwd(){ + return new Path(client_type === "deno" ? Deno.cwd() : window.location.href); + } + + /** + * returns true if the two routes are exactly equal + * @param routeA + * @param routeB + */ + static routesAreEqual(routeA: Path.route_representation, routeB: Path.route_representation) { + routeA = routeA instanceof Path ? routeA : Path.Route(routeA); + routeB = routeB instanceof Path ? routeB : Path.Route(routeB); + // check if all route sections are the same + return JSON.stringify(routeA.route) === JSON.stringify(routeB.route) + } + + /** + * @returns true if both paths are equal + */ + static equals(a: URL, b: Path) { + return a.toString() === b.toString() + } + + /** + * converts Path.representation to URL for absolute paths, or string for relative paths + * @param path + * @returns + */ + static #formatPath(path:Path.representation, abs_path_as_file_path = true) { + // wIndoWs + if (typeof path == "string" && path.match(/^\w:(\\|\/)/)) path = 'file:///' + path; + + // absolute url + if (path instanceof URL) return path; + else if (typeof path == "string" && path.match(/^[A-Za-z0-9]+\:/)) return new URL(path); + + // string, string [] + if (path instanceof Array) path = './'+path.join('/').replace(/^\//,''); // join, make relative and remove duplicate / at beginning + // for deno: absolute path becomes file path, not relative to origin + if (abs_path_as_file_path && client_type === "deno") { + if (typeof path == "string" && path.startsWith("/")) path = new URL(Path.DEFAULT_PROTOCOL + (Path.ProtocolDefaultPrefixes[Path.DEFAULT_PROTOCOL]??'') + path); // default to DEFAULT_PROTOCOL for absolute paths + } + if (typeof path == "string" && !(path.startsWith("/") || path.startsWith("./") || path.startsWith("../"))) path = "./" + path // assume file relative path without ./ + return path; + } + // returns true if the path is a URL or an url string + static pathIsURL(path:string|URL) { + return path instanceof URL || path?.match(/^[A-Za-z0-9]+\:/); + } + + + // returns true if protocol is http(s) + get is_web() { + return this.protocol ==

"http:" || this.protocol ==

"https:" + } + + isWeb(): this is Path<'https:'|'http:'> { + return this.protocol ==

"http:" || this.protocol ==

"https:" + } + + // returns true if pathname ends with / + get is_dir(): IsDir { + return this.pathname.endsWith("/") + } + + isDir(): this is Path { + return this.pathname.endsWith("/") + } + + /** + * get the root path (e.g. file://) + */ + get root(){ + return this.protocol + "//" + } + + /** + * is true if the path is an actual directory in the file system + */ + get fs_is_dir() { + if (this.is_web) return false; + if (client_type !== "deno") throw new Error("filesystem operations not supported"); + if (!this.fs_exists) return false; + return Deno.statSync(this.normal_pathname).isDirectory; + } + + /** + * returns true if the path is an actual directory in the file system + */ + async fsIsDir() { + if (this.is_web) return false; + if (client_type !== "deno") throw new Error("filesystem operations not supported"); + if (!await this.fsExists()) return false; + return (await Deno.stat(this.normal_pathname)).isDirectory; + } + + /** + * path sections as array + */ + get path(){ + const path = this.pathname.slice(1).split("/"); + if (path.at(-1) === "") path.pop(); + return path + } + + /** + * route sections (path + hash) as array + */ + get route(){ + const route = this.routename.slice(1).split("/"); + if (route.at(-1) === "") route.pop(); + return route + } + + /** + * filename extracted from pathname + */ + get filename() { + if (this.is_dir) throw new Error("path is directory"); + const path = this.path + return path[path.length-1]; + } + + /** + * directory name extracted from pathname + */ + get dirname() { + if (!this.is_dir) throw new Error("path is file"); + const path = this.path + return path[path.length-1]; + } + + /** + * filename or directory name + */ + get name(){ + if (this.is_dir) return this.dirname; + else return this.filename + } + + /** + * full path + hash + */ + get routename() { + return this.getRoutename(true) + } + + getRoutename(includeSearch = true) { + return this.pathname + (includeSearch ? this.search : "") + this.hash; + } + + /** + * the last extension (everything after the last '.') + */ + get ext(){ + return this.pathname.match(/\.([^\.\/\\]+)$/)?.[1] + } + + /** + * an array of all extensions, sorted from last to first + */ + get exts(){ + return this.pathname.match(/(\.([^\.\/\\]+))+$/)?.[0].split(".").slice(1).reverse() + } + + /** + * parent directory + */ + get parent_dir(): Path { + return this.is_dir ? new Path('../', this) : new Path('./', this); + } + + /** + * get pathname for filesystems, not encoded for URLs + * also handles windows absolute paths (e.g. C:/) + */ + get normal_pathname() { + const path = decodeURIComponent(this.pathname); + if (path.match(/^\/.\:\//)) return path.slice(1) + return path + } + + /** + * is true if file/directory exists in filesystem + */ + get fs_exists() { + if (this.is_web) return false; + if (client_type !== "deno") throw new Error("filesystem operations not supported"); + try { + Deno.statSync(this.normal_pathname); + return true + } + catch { + return false + } + } + + /** + * returns true if web path returns OK status + * @returns + */ + async webExists() { + if (!this.is_web) return false; + try { + return (await fetch(this)).ok + } + catch { + return false + } + } + + /** + * return true if file/directory exists in filesystem + */ + async fsExists() { + if (this.is_web) return false; + if (client_type !== "deno") throw new Error("filesystem operations not supported"); + try { + await Deno.stat(this.normal_pathname); + return true + } + catch { + return false + } + } + + /** + * returns true if path exists on filesystem or web + * @returns + */ + async exists() { + return await this.fsExists() || await this.webExists(); + } + + /** + * Returns the path content as an ArrayBuffer. + * Fetches from web if http[s]:// url, loads local file content (in deno), if file:// url + */ + async getContent() { + if (this.is_web) { + return (await fetch(this)).arrayBuffer() + } + else { + return Deno.readFile(this.normal_pathname); + } + } + + /** + * Returns the path content as a string. + * Fetches from web if http[s]:// url, loads local file content (in deno), if file:// url + */ + async getTextContent() { + if (this.is_web) { + const res = await fetch(this); + if (res.ok) return res.text() + else throw res.text(); + } + else { + return Deno.readTextFile(this.normal_pathname); + } + } + + + /** + * Returns the first extension from the given extensions that matches the current path + * @param extensions list of file extensions (without a leading ".") + * @returns + */ + hasFileExtension(...extensions:string[]) { + for (const extension of extensions) { + if (this.pathname.endsWith("." + extension)) return extension; + } + return false; + } + + /** + * Returns a new Path without the file extension + * @param remove_all remove all extensions (e.g .tar.gz) + * @returns + */ + getWithoutFileExtension(remove_all = false): Path { + if (remove_all) return new Path(this.toString().replace(/(\.[^\.\/\\]+)+$/, "")) + else return new Path(this.toString().replace(/\.[^\.\/\\]+$/, "")) + } + + /** + * Returns a new Path with a different file extension + * @param ext the new file extension + * @param replace_all replace all extensions (e.g .tar.gz) + * @returns + */ + getWithFileExtension(ext:string, replace_all = false): Path { + if (this.ext) { + if (replace_all) return new Path(this.toString().replace(/(\.[^\.\/\\]+)+$/, "." + ext)) + else return new Path(this.toString().replace(/\.[^\.\/\\]+$/, "." + ext)) + } + else { + if (this.is_dir) return new Path(this.toString().slice(0, -1) + "." + ext + "/"); + else return new Path(this.toString() + "." + ext); + } + } + + /** + * Replaces a given file extension with a different extension and returns a new Path + * @param prev + * @param ext + * @returns + */ + replaceFileExtension(prev:string, ext:string): Path { + return new Path(this.toString().replace(new RegExp('\\.' + prev.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") /* escape string for regex */ + '$'), "." + ext)) + } + + /** + * Gets child path, existing hash is lost + * throws an error if the current path is not a directory path + * @param child child path representation (must be relative or Path with route protocol type) + * @returns + */ + getChildPath(child: string|string[]|Path.Route):Path { + if (!this.is_dir) throw new Error("cannot get child path of non-directory path"); + // make sure it is a relative path + let formatted_child = Path.#formatPath(child, false); + if (typeof formatted_child == "string" && formatted_child.startsWith("/")) formatted_child = formatted_child.slice(1); + // invalid - child is absolute url + if (formatted_child instanceof URL) { + if (formatted_child.protocol === Path.RouteProtocol) formatted_child = "." + formatted_child.pathname + formatted_child.hash; + else throw new Error("invalid child path: " + child + " - cannot be an absolute URL"); + } + return new Path(formatted_child, this); + } + + /** + * Gets child route, keep hash routes + * @param child child route + */ + getChildRoute(child: string|string[]|Path.Route) { + let formatted_child = Path.#formatPath(child, false); + // invalid - child is absolute url + if (formatted_child instanceof URL) { + if (formatted_child.protocol === Path.RouteProtocol) formatted_child = formatted_child.pathname + formatted_child.hash; + else throw new Error("invalid child path: " + child + " - cannot be an absolute URL"); + } + let current_path = this.toString(); + if (!current_path.endsWith("/")) current_path += "/"; + if (formatted_child.startsWith("/")) formatted_child = formatted_child.slice(1); + else if (formatted_child.startsWith("./")) formatted_child = formatted_child.slice(2); + else if (formatted_child.startsWith("../")) throw new Error("cannot resolve child route " + formatted_child); + + return new Path(current_path + formatted_child); + } + + getWithChangedParent

(from:string|URL, to:Path

): Path + getWithChangedParent(from:string|URL, to:string|URL): Path + getWithChangedParent(from:string|URL, to:string|URL) { + const from_path = new Path(from); + const to_path = new Path(to); + return new Path(this.toString().replace(from_path.toString(), to_path.toString())) + } + + getAsRelativeFrom(path:string|URL) { + let _path = new Path(path); + if (!_path.is_dir) _path = _path.parent_dir; + + if (!relative) throw new Error("relative path utils only supported in deno") + let rel = relative(_path.pathname, this.pathname); + if (!(rel.startsWith("./") || rel.startsWith("../"))) rel = "./" + rel; + if (rel.startsWith("./../")) rel = rel.replace("./../", "../") + if (rel.startsWith("./..\\")) rel = rel.replace("./..\\", "../") + if (this.is_dir && !rel.endsWith("/")) rel += "/"; + + // re-add query params + if (this.search) rel += this.search; + + return rel; + } + + asDir(): Path { + return Path.dir(this); + } + + // convert to dir if fs dir, otherwise file + asFSPath(): Path { + if (this.fs_is_dir) return Path.dir(this); + else return Path.file(this); + } + + isChildOf (parent_path:string|URL) { + parent_path = new Path(parent_path); + return this.parent_dir.toString().startsWith(parent_path.toString()) + } + + // filesystem utils - create dir + fsCreateIfNotExists(){ + if (client_type !== "deno") throw new Error("filesystem operations not supported"); + if (!this.is_dir) throw new Error("cannot create directory for non-directory path"); + + try { + Deno.statSync(this) + } + catch { + Deno.mkdirSync(this, {recursive: true}); + } + return this; + } + +} + +export namespace Path { + + export type representation = string|string[]|URL; + export type route_representation = string[]|Path.Route; + + export type protocol = `${string}:` + + export enum Protocol { + HTTP = 'http:', + HTTPS = 'https:', + File = 'file:', + } + + export const DEFAULT_PROTOCOL:Path.protocol = Protocol.File; + + export const ProtocolDefaultPrefixes = { + [Protocol.HTTP]: '//unknown', + [Protocol.HTTPS]: '//unknown', + [Protocol.File]: '//', + } as const + + export const RouteProtocol = 'route:' satisfies protocol; + + function getPathWithProtocol(path: representation|undefined, protocol: T) { + // change protocol + if ((path instanceof URL || typeof path == "string") && Path.pathIsURL(path) && !path.toString().startsWith(protocol)) { + path = new Path(path.toString()).routename; + } + return new Path(path, protocol + (ProtocolDefaultPrefixes[protocol]??'/')) + } + + export function HTTP(path?: representation) { + // relative path + if (typeof path == "string" && !path.startsWith("/")) path = new Path(path, getCallerFile()) + return getPathWithProtocol(path, Protocol.HTTP) + } + export function HTTPS(path?: representation) { + // relative path + if (typeof path == "string" && !path.startsWith("/")) path = new Path(path, getCallerFile()) + return getPathWithProtocol(path, Protocol.HTTPS) + } + export function File(path?: representation) { + // relative path + if (typeof path == "string" && !path.startsWith("/")) path = new Path(path, getCallerFile()) + return getPathWithProtocol(path, Protocol.File) + } + export function Route(path?: representation) { + return getPathWithProtocol(path, RouteProtocol) + } + + export type HTTP = ReturnType + export type HTTPS = ReturnType + export type File = ReturnType + export type Route = ReturnType + +} \ No newline at end of file From 56fa7998146397bccf2be7ec47076f447917441a Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 01:26:35 +0100 Subject: [PATCH 02/60] handle init with custom storage locations --- init.ts | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/init.ts b/init.ts index 9629e810..df701992 100644 --- a/init.ts +++ b/init.ts @@ -3,7 +3,7 @@ import { Pointer } from "./runtime/pointers.ts"; import { LOCAL_ENDPOINT } from "./types/addressing.ts"; import { client_type } from "./utils/constants.ts"; import { Storage, registerStorageAsPointerSource } from "./runtime/storage.ts"; -import { logger } from "./utils/global_values.ts"; +import { cwdURL, logger } from "./utils/global_values.ts"; import { IndexedDBStorageLocation } from "./runtime/storage-locations/indexed-db.ts"; import { LocalStorageLocation } from "./runtime/storage-locations/local-storage.ts"; import { DenoKVStorageLocation } from "./runtime/storage-locations/deno-kv.ts"; @@ -11,6 +11,8 @@ import { loadEternalValues } from "./utils/eternals.ts"; import { DX_BOUND_LOCAL_SLOT } from "./runtime/constants.ts"; import { verboseArg } from "./utils/logger.ts"; import { MessageLogger } from "./utils/message_logger.ts"; +import { Path } from "./utils/path.ts"; +import { clear } from "./utils/args.ts"; /** @@ -24,7 +26,24 @@ export async function init() { // @ts-ignore NO_INIT if (!globalThis.NO_INIT) { + + // custom storage module (storage.ts next to .dx config) + let storageInitModule: Path|undefined if (client_type == "browser") { + // TODO: handle storage.ts URL in browser + // storageInitModule = new URL('/storage.ts', globalThis.location.href) + } + else if (client_type == "deno") { + // TODO: dynamic storage.ts location - use uix path backend/storage.ts as workaround + storageInitModule = new Path('./backend/storage.ts', cwdURL) + } + + if (await storageInitModule?.fsExists()) { + logger.info("Initializing custom storage configuration (" + storageInitModule!.normal_pathname + ")") + await import(storageInitModule!.normal_pathname); + } + + else if (client_type == "browser") { await Storage.addLocation(new IndexedDBStorageLocation(), { modes: [Storage.Mode.SAVE_ON_CHANGE, Storage.Mode.SAVE_PERIODICALLY], primary: true @@ -50,9 +69,11 @@ export async function init() { }) } } - + if (Storage.locations.size === 0 && client_type !== "worker") + logger.warn(`No storage was created in storage.ts - Please check the configuration because eternal pointers can not be stored persistently otherwise.`) } + // listen for endpoint changes Runtime.onEndpointChanged((endpoint) => { Pointer.pointer_prefix = endpoint.getPointerPrefix(); @@ -126,5 +147,9 @@ export async function init() { if (!globalThis.NO_INIT) await loadEternalValues(); // enables message logger when running with -v - if (verboseArg) MessageLogger.enable() + if (verboseArg) MessageLogger.enable(); + + if (clear) { + await Storage.clearAndReload(); + } } From 41ea10d2d698488eb5d1a7cee0953508cfad6ff4 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 01:27:05 +0100 Subject: [PATCH 03/60] disable interface disconnect on supranet reconnect --- network/supranet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/network/supranet.ts b/network/supranet.ts index 26e5e71e..273237e9 100644 --- a/network/supranet.ts +++ b/network/supranet.ts @@ -169,7 +169,8 @@ export class Supranet { // find node for available channel const [node, channel_type] = await this.getNode(via_node) - await InterfaceManager.disconnect() // first disconnect completely + // TODO: clean disconnect with GOODBYE? Never disconnect interfaces? + // await InterfaceManager.disconnect() // first disconnect completely const connected = await InterfaceManager.connect(channel_type, node) Runtime.setMainNode(node); From c81950c164d577d350b60e0857f91160d56330c7 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 01:27:31 +0100 Subject: [PATCH 04/60] add .size support for StorageSet --- types/storage_set.ts | 71 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/types/storage_set.ts b/types/storage_set.ts index 2d2197b5..95635256 100644 --- a/types/storage_set.ts +++ b/types/storage_set.ts @@ -36,8 +36,9 @@ export class StorageWeakSet { async add(value: V) { const storage_key = await this.getStorageKey(value); - if (await this._has(storage_key)) return; // already exists - return this._add(storage_key, null); + if (await this._has(storage_key)) return this; // already exists + await this._add(storage_key, null); + return this; } protected _add(storage_key:string, value:V|null) { this.activateCacheTimeout(storage_key); @@ -90,13 +91,75 @@ export class StorageWeakSet { */ export class StorageSet extends StorageWeakSet { + #size_key?: string + protected get _size_key() { + if (!this.#size_key) this.#size_key = 'dxset.size::'+(this as any)[DX_PTR].idString()+'.'; + return this.#size_key; + } + + #size?: number; + + get size() { + if (this.#size == undefined) throw new Error("size not yet available. use getSize() instead"); + return this.#size; + } + + async getSize() { + if (this.#size != undefined) return this.#size; + else { + await this.#determineSizeFromStorage(); + return this.#size! + } + } + + /** + * Sets this.#size to the correct value determined from storage. + */ + async #determineSizeFromStorage() { + const cachedSize = await Storage.getItem(this._size_key); + const calculatedSize = await Storage.getItemCountStartingWith(this._prefix); + if (cachedSize !== calculatedSize) { + if (cachedSize != undefined) + logger.warn(`Size mismatch for StorageSet (${(this as any)[DX_PTR].idString()}) detected. Setting size to ${calculatedSize}`) + await this.#updateSize(calculatedSize); + } + else this.#size = calculatedSize; + } + + async #updateSize(newSize: number) { + this.#size = newSize; + await Storage.setItem(this._size_key, newSize); + } + + async #incrementSize() { + await this.#updateSize(await this.getSize() + 1); + } + + async #decrementSize() { + await this.#updateSize(await this.getSize() - 1); + } + + /** * Appends a new value to the StorageWeakSet. */ async add(value: V) { const storage_key = await this.getStorageKey(value); - if (await this._has(storage_key)) return; // already exists - return this._add(storage_key, value); + if (await this._has(storage_key)) return this; // already exists + await this._add(storage_key, value); + await this.#incrementSize(); + return this; + } + + async delete(value: V) { + const wasDeleted = await super.delete(value); + if (wasDeleted) await this.#decrementSize(); + return wasDeleted; + } + + async clear(): Promise { + await super.clear(); + await this.#updateSize(0); } /** From eb149739312949ef5655993f73040b59bece90a9 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 01:49:55 +0100 Subject: [PATCH 05/60] fix clear arg --- init.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/init.ts b/init.ts index df701992..008dd561 100644 --- a/init.ts +++ b/init.ts @@ -12,7 +12,6 @@ import { DX_BOUND_LOCAL_SLOT } from "./runtime/constants.ts"; import { verboseArg } from "./utils/logger.ts"; import { MessageLogger } from "./utils/message_logger.ts"; import { Path } from "./utils/path.ts"; -import { clear } from "./utils/args.ts"; /** @@ -149,7 +148,10 @@ export async function init() { // enables message logger when running with -v if (verboseArg) MessageLogger.enable(); - if (clear) { - await Storage.clearAndReload(); + if (client_type == "deno") { + const { clear } = await import("./utils/args.ts"); + if (clear) { + await Storage.clearAndReload(); + } } } From 3c4ce6bcf189c5e76eb82fa183eb305188a595d1 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 15:06:50 +0100 Subject: [PATCH 06/60] fix typo --- docs/manual/01 Introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manual/01 Introduction.md b/docs/manual/01 Introduction.md index 5cec87e9..58d517fc 100644 --- a/docs/manual/01 Introduction.md +++ b/docs/manual/01 Introduction.md @@ -2,7 +2,7 @@ > [!WARNING] > The current implementation of the DATEX JavaScript Library is still a beta version. -> We are activly working on a new stable [Rust implementation](https://github.com/unyt-org/datex-core) that will be much more performant. +> We are actively working on a new stable [Rust implementation](https://github.com/unyt-org/datex-core) that will be much more performant. The DATEX JavaScript Library (*DATEX JS*) enables fine-grained reactivity with cross-device processing including data synchronisation. From 5b72bf0b7481d2e21481c368994dece91d89ebc3 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 17:05:18 +0100 Subject: [PATCH 07/60] add Storage.getItemCountStartingWith, return action success state from removeItem --- runtime/storage.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/runtime/storage.ts b/runtime/storage.ts index 9c9c7c93..971878ea 100644 --- a/runtime/storage.ts +++ b/runtime/storage.ts @@ -190,6 +190,10 @@ export class Storage { static #locations = new Map>() static #auto_sync_enabled = false; + public static get locations() { + return this.#locations; + } + // set options for storage location and enable public static addLocation(location:L, options:storage_location_options) { this.#locations.set(location, options); @@ -892,6 +896,16 @@ export class Storage { })() } + public static async getItemCountStartingWith(prefix:string, location?:StorageLocation) { + const keyIterator = await Storage.getItemKeys(location); + let count = 0; + for (const key of keyIterator) { + if (key.startsWith(prefix)) count++; + } + return count + } + + public static async getPointerKeys(location?:StorageLocation){ // for specific location @@ -994,12 +1008,17 @@ export class Storage { else return false; } - public static async removeItem(key:string, location?:StorageLocation):Promise { + public static async removeItem(key:string, location?:StorageLocation):Promise { logger.debug("Removing item '" + key + "' from storage" + (location ? " (" + location.name + ")" : "")) // remove from specific location - if (location) return location.removeItem(key); + if (location) { + // TODO: handle hasItem() internally in storage locations + const itemExists = await location.hasItem(key); + await location.removeItem(key); + return itemExists; + } // remove from all else { Storage.cache.delete(key); // delete from cache @@ -1007,9 +1026,13 @@ export class Storage { // clear dependencies this.updateItemDependencies(key, []) + let itemExists = false; for (const location of this.#locations.keys()) { + // TODO: handle hasItem() internally in storage locations + if (!itemExists) itemExists = await location.hasItem(key); await location.removeItem(key); } + return itemExists; } } From 904458462eb6d9f021dbccd61e58100c005579b4 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 17:05:46 +0100 Subject: [PATCH 08/60] refactoring --- runtime/storage-locations/indexed-db.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/storage-locations/indexed-db.ts b/runtime/storage-locations/indexed-db.ts index 4cdb4265..deb33d6d 100644 --- a/runtime/storage-locations/indexed-db.ts +++ b/runtime/storage-locations/indexed-db.ts @@ -24,9 +24,9 @@ export class IndexedDBStorageLocation extends AsyncStorageLocation { } async setItem(key: string,value: unknown) { - const inserted_ptrs = new Set(); - await datex_item_storage.setItem(key, Compiler.encodeValue(value, inserted_ptrs)); - return inserted_ptrs; + const dependencies = new Set(); + await datex_item_storage.setItem(key, Compiler.encodeValue(value, dependencies)); + return dependencies; } async getItem(key: string, conditions: ExecConditions): Promise { const buffer = await datex_item_storage.getItem(key); @@ -67,9 +67,9 @@ export class IndexedDBStorageLocation extends AsyncStorageLocation { } async setPointer(pointer: Pointer): Promise>> { - const inserted_ptrs = new Set(); - await datex_pointer_storage.setItem(pointer.id, Compiler.encodeValue(pointer, inserted_ptrs, true, false, true)); - return inserted_ptrs; + const dependencies = new Set(); + await datex_pointer_storage.setItem(pointer.id, Compiler.encodeValue(pointer, dependencies, true, false, true)); + return dependencies; } async getPointerValue(pointerId: string, outer_serialized: boolean, conditions: ExecConditions): Promise { const buffer = await datex_pointer_storage.getItem(pointerId); From 036677de3d07fe49a92fd142183b825ae9b5a3aa Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 17:07:55 +0100 Subject: [PATCH 09/60] fix instanceof for Pointer/PointerProperty --- runtime/pointers.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/pointers.ts b/runtime/pointers.ts index d1c9b4df..5622ae27 100644 --- a/runtime/pointers.ts +++ b/runtime/pointers.ts @@ -559,6 +559,9 @@ export type InferredPointerProperty = PointerProperty extends Ref { + // override hasInstance from Ref + static [Symbol.hasInstance]: (val: unknown) => val is PointerProperty + #leak_js_properties: boolean public pointer?: Pointer; @@ -1089,6 +1092,9 @@ const observableArrayMethods = new Set([ /** Wrapper class for all pointer values ($xxxxxxxx) */ export class Pointer extends Ref { + // override hasInstance from Ref + static [Symbol.hasInstance]: (val: unknown) => val is Pointer + /** STATIC */ /** Pointer observers */ From 229a55ba3a4694e2f66632319488a659fcc5f53c Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 17:33:15 +0100 Subject: [PATCH 10/60] clear endpoints with access permissions (unrelated) --- runtime/pointers.ts | 50 ++++++++++++++++++++++++++++++++++++++------- runtime/runtime.ts | 1 + 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/runtime/pointers.ts b/runtime/pointers.ts index 5622ae27..efb28df3 100644 --- a/runtime/pointers.ts +++ b/runtime/pointers.ts @@ -1956,6 +1956,9 @@ export class Pointer extends Ref { #allowed_access?: target_clause // who has access to this pointer?, undefined = all + // reverse mapping for allowed_access + static #allowed_access_by_endpoint = new Map>().setAutoDefault(IterableWeakSet); + #garbage_collectable = false; #garbage_collected = false; @@ -2031,7 +2034,10 @@ export class Pointer extends Ref { public grantAccessTo(endpoint: Endpoint, _force = false) { if (!_force && !Runtime.OPTIONS.PROTECT_POINTERS) throw new Error("Read permissions are not enabled per default (set Datex.Runtime.OPTIONS.PROTECT_POINTERS to true)") if (!this.#allowed_access || this.#allowed_access == BROADCAST) this.#allowed_access = new Disjunction() - if (this.#allowed_access instanceof Disjunction) this.#allowed_access.add(endpoint) + if (this.#allowed_access instanceof Disjunction) { + this.#allowed_access.add(endpoint) + Pointer.#allowed_access_by_endpoint.getAuto(endpoint).add(this); + } else throw new Error("Invalid access filter, cannot add endpoint (TODO)") } @@ -2052,7 +2058,14 @@ export class Pointer extends Ref { */ public revokeAccessFor(endpoint: Endpoint, _force = false) { if (!_force && !Runtime.OPTIONS.PROTECT_POINTERS) throw new Error("Read permissions are not enabled per default (set Datex.Runtime.OPTIONS.PROTECT_POINTERS to true)") - if (this.#allowed_access instanceof Disjunction) this.#allowed_access.delete(endpoint) + if (this.#allowed_access instanceof Disjunction) { + this.#allowed_access.delete(endpoint); + const allowed_access_list = Pointer.#allowed_access_by_endpoint.get(endpoint); + if (allowed_access_list) { + allowed_access_list.delete(this); + if (allowed_access_list.size == 0) Pointer.#allowed_access_by_endpoint.delete(endpoint); + } + } else throw new Error("Invalid access filter, cannot add endpoint (TODO)") } @@ -3270,7 +3283,7 @@ export class Pointer extends Ref { public static enablePeriodicSubscriberCleanup(interval = 15 * 60) { logger.debug(`periodic pointer subscriber cleanup enabled (interval: ${interval} seconds)`); if (Pointer.#periodicSubscriberCleanup) clearInterval(Pointer.#periodicSubscriberCleanup); - Pointer.#periodicSubscriberCleanup = setInterval(() => this.cleanupSubscribers(), interval * 1000); + Pointer.#periodicSubscriberCleanup = setInterval(() => this.cleanupEndpoints(), interval * 1000); } /** @@ -3285,14 +3298,23 @@ export class Pointer extends Ref { } /** - * Removes all subscribers that are no longer online + * Iterates over all subscribers and access endpoints + */ + static *#subscribersAndAccessEndpoints() { + for (const endpoint of Pointer.#endpoint_subscriptions.keys()) yield endpoint; + for (const endpoint of Pointer.#allowed_access_by_endpoint.keys()) yield endpoint; + } + + /** + * Removes all referenced endpoints that are no longer online */ - public static async cleanupSubscribers() { - logger.debug("cleaning up subscribers"); + public static async cleanupEndpoints() { + logger.debug("cleaning up endpoints with subscriptions or access permissions"); - for (const endpoint of Pointer.#endpoint_subscriptions.keys()) { + for (const endpoint of this.#subscribersAndAccessEndpoints()) { if (!(await endpoint.isOnline())) { this.clearEndpointSubscriptions(endpoint); + this.clearEndpointPermissions(endpoint) } } } @@ -3311,6 +3333,20 @@ export class Pointer extends Ref { if (removeCount) logger.debug("removed " + removeCount + " subscriptions for " + endpoint); } + /** + * Removes all permissions for an endpoint given with grantAccessTo + */ + public static clearEndpointPermissions(endpoint: Endpoint) { + if (!Runtime.OPTIONS.PROTECT_POINTERS) return; // ignore if pointer protection is disabled + + let removeCount = 0; + for (const pointer of Pointer.#allowed_access_by_endpoint.get(endpoint) ?? []) { + pointer.revokeAccessFor(endpoint); + removeCount++; + } + if (removeCount) logger.debug("removed " + removeCount + " pointer access permissions for " + endpoint); + } + // updates are from datex (external) and should not be distributed again or local update -> should be distributed to subscribers #update_endpoints: Disjunction; // endpoint to update diff --git a/runtime/runtime.ts b/runtime/runtime.ts index f7427e3f..07c629d1 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -1823,6 +1823,7 @@ export class Runtime { logger.debug("GOODBYE from " + header.sender) header.sender.setOnline(false) Pointer.clearEndpointSubscriptions(header.sender) + Pointer.clearEndpointPermissions(header.sender) } else { logger.error("ignoring unsigned GOODBYE message") From a14f902bfb7945d9b8350c96e126980ef2425b30 Mon Sep 17 00:00:00 2001 From: benStre Date: Tue, 30 Jan 2024 22:55:26 +0100 Subject: [PATCH 11/60] fix unresolved pointer loading promises --- runtime/pointers.ts | 21 ++++++++++++++------- runtime/runtime.ts | 34 +++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/runtime/pointers.ts b/runtime/pointers.ts index efb28df3..fa6e5546 100644 --- a/runtime/pointers.ts +++ b/runtime/pointers.ts @@ -1377,8 +1377,15 @@ export class Pointer extends Ref { // load from storage or request from remote endpoint if pointer not yet loaded static load(id:string|Uint8Array, SCOPE?:datex_scope, only_load_local = false, sender_knows_pointer = true, allow_failure = true): Promise|Pointer|LazyPointer { - const id_string = Pointer.normalizePointerId(id); + // pointer already exists + const existing_pointer = Pointer.get(id); + if (existing_pointer?.value_initialized) { + // check read permissions + existing_pointer.assertEndpointCanRead(SCOPE?.sender) + return existing_pointer; + } + const id_string = Pointer.normalizePointerId(id); // only load if local pointer id if (SCOPE?.exec_conditions?.onlyLocalPointers) { const origin = Pointer.getOriginFromPointerId(id_string); @@ -1388,9 +1395,7 @@ export class Pointer extends Ref { } if (SCOPE) { - // recursive pointer loading! TODO if (this.loading_pointers.get(id_string)?.scopeList.has(SCOPE)) { - // logger.debug("recursive pointer loading: $"+ id_string); return new LazyPointer(id_string) } } @@ -1403,7 +1408,6 @@ export class Pointer extends Ref { this.loading_pointers.set(id_string, null as any); const loadPromise = this.handleLoad(id_string, id, SCOPE, only_load_local, sender_knows_pointer, allow_failure); - // only add load data if load not already finished if (this.loading_pointers.has(id_string)) { this.addLoadingPointerPromise(id_string, loadPromise, SCOPE); @@ -2013,11 +2017,14 @@ export class Pointer extends Ref { if ( Runtime.OPTIONS.PROTECT_POINTERS && !(endpoint == Runtime.endpoint) - && this.is_origin - && (!endpoint || !Logical.matches(endpoint, this.allowed_access, Target)) + && this.is_origin + && ( + !endpoint || + (this.allowed_access instanceof Disjunction && this.allowed_access.size==0) || // TODO: this case is just added because Logical.matches currently always returns true for an empty Disjunction, which is not intended here + !Logical.matches(endpoint, this.allowed_access, Target)) && (endpoint && !Runtime.trustedEndpoints.get(endpoint.main)?.includes("protected-pointer-access")) ) { - throw new PermissionError("Endpoint has no read permissions for this pointer ("+this.idString()+")"); + throw new PermissionError("Endpoint "+endpoint+" has no read permissions for pointer "+this.idString()+" (origin: "+this.origin+")"); } } diff --git a/runtime/runtime.ts b/runtime/runtime.ts index 07c629d1..1ae7e4ab 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -3196,10 +3196,11 @@ export class Runtime { // ptrs if (INNER_SCOPE.waiting_ptrs?.size) { for (const p of INNER_SCOPE.waiting_ptrs) { + const isSet = p[1] == undefined; + const isInit = typeof p[1] == "object"; + try { if (SCOPE.header.type==ProtocolDataType.UPDATE) p[0].excludeEndpointFromUpdates(SCOPE.sender); - const isSet = p[1] == undefined; - const isInit = typeof p[1] == "object"; if (isSet || isInit) { const ptr = p[0].setValue(el); @@ -3225,6 +3226,10 @@ export class Runtime { else await Runtime.runtime_actions.handleAssignAction(SCOPE, p[1], null, null, el, p[0]); // other action on pointer } catch (e) { + if (p[1]?.reject) { + p[1].reject(e); + Pointer.loading_pointers.delete(ptr.id); + } p[0].enableUpdatesForAll(); throw e; }; @@ -6972,14 +6977,25 @@ export class Runtime { // pointer.is_persistent = true; SCOPE.current_index += init_block_size; // jump to end of init block } - // does not exist - init + // does not exist: init, or no permission catch (e) { - if (!SCOPE.inner_scope.waiting_ptrs) SCOPE.inner_scope.waiting_ptrs = new Set(); - const tmp_ptr = Pointer.create(id); - // add pointer init promise for recursive init - const {promise, resolve, reject} = Promise.withResolvers() - Pointer.addLoadingPointerPromise(id, promise, SCOPE); - SCOPE.inner_scope.waiting_ptrs.add([tmp_ptr, {resolve, reject}]); // assign next value to pointer; + + // pointer does exist but no permission + if (e instanceof PermissionError) { + throw e; + } + + // pointer does not exist + else { + if (!SCOPE.inner_scope.waiting_ptrs) SCOPE.inner_scope.waiting_ptrs = new Set(); + const tmp_ptr = Pointer.create(id); + // add pointer init promise for recursive init + const {promise, resolve, reject} = Promise.withResolvers(); + Pointer.addLoadingPointerPromise(id, promise, SCOPE); + // TODO: make sure resolve or reject is called at some point or the promise is removed + SCOPE.inner_scope.waiting_ptrs.add([tmp_ptr, {resolve, reject}]); // assign next value to pointer; + } + } break; From 81b2a85ced1cc6138e5fc1e4a714d6923231d50f Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 1 Feb 2024 13:26:23 +0100 Subject: [PATCH 12/60] fix init --- init.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/init.ts b/init.ts index 008dd561..9a33ce6b 100644 --- a/init.ts +++ b/init.ts @@ -39,7 +39,15 @@ export async function init() { if (await storageInitModule?.fsExists()) { logger.info("Initializing custom storage configuration (" + storageInitModule!.normal_pathname + ")") - await import(storageInitModule!.normal_pathname); + try { + await import(storageInitModule!.normal_pathname); + } + catch (e) { + console.error(e) + } + + if (Storage.locations.size === 0) + logger.warn(`No storage location was added in storage.ts - cannot store persistent data!`) } else if (client_type == "browser") { @@ -68,8 +76,7 @@ export async function init() { }) } } - if (Storage.locations.size === 0 && client_type !== "worker") - logger.warn(`No storage was created in storage.ts - Please check the configuration because eternal pointers can not be stored persistently otherwise.`) + } From e0515a7026209bd570a93dd9988904aefc3c8e2f Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 1 Feb 2024 13:26:41 +0100 Subject: [PATCH 13/60] update datex wasm --- wasm/adapter/pkg/datex_wasm_bg.wasm | Bin 806629 -> 806073 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/wasm/adapter/pkg/datex_wasm_bg.wasm b/wasm/adapter/pkg/datex_wasm_bg.wasm index ec11a9acbdb8b133c1e04154ab838320e3617218..5413551fe8adb9863f9f87e026358d62eb5028de 100644 GIT binary patch delta 156544 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 E4*yJRRwZBhuoCEVWy# zO{<(E*sU1NuLT>zX3OLu%+*ZwiA-$8NQxZMB{9Q)#}LdvRLi`AxzK3!6|5=C@PB*- zyNPm>hBB982#ihT@fYWsQQK2kH8#mxhO+tWod3j7wu7;+#|zO);~41b5vOemRQG>8=kkrXt9p5h?&N4s~3RtzXF`I?HtB(@ZaxOGcwxE97sZ*^>bC z$QU*QkJDqYRGsygjAd;ZCC9N_joBGgT_VSfo=zUm#-PG`<5{P+I`+)O0CuXNW=5We zvM^)R+_YcKTDH;)=0nribpB^5rGp8hri%Z{tJxKtWy_3fVWFe4Ea=7BB>_qunNq5! zs~)DJl+$NPAZSyytz>dQLmcL(zne&~$`#)F{*iw>BV%PYyZ(v*SAr}AbH-UGa zkWplVgJyme1X@MQkmYdh2TIAEH#488_z~~wn=xFB*Bp{L_p&(o#Vza>mh10zD=UX(>W{shb=I!Q4q~^u@r?&JW|Wz%L>PG3 z$%%qsF-%CYGLWJ$JwlWD6G%|@Gj@M^YNK3oC;N{zjY>Z75B(>j@5K1Qg*ced5)A0- zAAS#Ob*WsKB_r=;KJ>wlJ`?~HF?6_p`4nVYb>ii~2UwytNAK|+53mK){dlsf1#a|@B)q*?1Zo5cfOe(M&hk@L>~d>#~^>C6lJHFCfF0Kg70P{q2HMlSmL53rmf$ z%)*;!Db@!wiYOyN91CVtQ${bba#5g30p3J!QLQrk*FMbFG24=jC|zNZgVWgndD$$M zBp-Z)9jcY>U;HSuusEY87F9bo9x7EJf1JsB%0rLAf;lS_A6J&e81?W!^*9@5#Z=w; z44a}+KfBCi&FDF5CTlzTSf)Z-3mC1}jsR#9bP@3#Tcd#{B z?7w|B8^+`C9RVCj;Vv^h;;^M86_qxZwU_3(EMA_0cL6%3<#ViW#HSS0RE2fvkev7& zyUu7z-{C;hs8G`m^5^H+zl>ts{iWiBQ1Ly0S2-8(J`2EG-|6dFul963h0V zUce$4|HLda7qZ4Oei0_j3Hi(-HZE30ISrsd9JeJ>xUi?s_E#)|4Fc;dYB9$1ge6ig z&V;U5xR}ME)fv$H?vsx~Gp1DWmp~N{8PA-x4)gIDJ z>4%V^G?S50O*K>oAytk9qhv|2Du*F)TK@h#`$r>Hp=K9gf&06ushs3v^9`oBuoDGS zpqyO{cC=*)w24uajNKH9Ize|)QJ)vsdB%Q`9kW;qd97soSv9>s1EK!#CDulMp2bEQ zEpa!GTH-pckn265T*Z{@~4u9k4S8CJUGi1xqi8vy%|0=qk@&?__tU- zI&5B{G)#B(@ZY(D&E(K1{%_u9ADhP=Bb+o>qoT=+8kp9E$O$q^sdyu$A|R0}RY#9d zS*RW194Py*V*SE2Uy!5~^0`&)M6|92si7Skkg8RznM_>8TKd=Ju@;P!-R{+_6P_=w zVZC~XREwGu0df^R>CXrB8mJqCxIQ9siOQ7suVL-lgfNAa3-H#~J@WlEu##rW{`t&> z?dC1{EU~#VXvmmEe5$y76vBM5YeSTaGg~gnhd7;w&{ur%Z zD`ZV-RgaWM3)utpp}3Ca$@ey24A85aSp%7~1z*EZ6R$lU`?s(jMyknK>~i{gW^YYac-mE5cgIy&tiA8wZdP9nj+*oOwD`lddv-2aDC~y5;*j zSfba^Q^)Emu5EQQO6z7+*UeZ`5m4X;(Db?)YwKog8(BB!Slx`$x*6$*>!7JtHRP*B z?2Y>5U{rKK7pr>yw?AeFc=Qn*EMYfFu?)^-(pL<(!*BAJVz!PSvCHye_>_K=+dpL` zY`c8%Gib;o^4w?aM#~X9E|$obKZE!^{yC!Nw_D-U*VB`Wu_k`-Io8!9@}tk$4eV8a zs}eSy0To3@X(9*69MWCPn#&El*u%}z%V0Fl#~)_}eQ*%YLQ${}sRB7{H|xrl$;WrI z#OUn3sMSdn;ejRYjooZeYd;;DVj-!pszU~+y2c{X*f{L0>F|a-OQd-Z1jH{#?!ij7 zNfzy4W1H==dk`Tl%<%Y&%2Gg067zMaol99`Rw9R%LMJSe50xR^@ zeXQ*j7xVz?wFja?4n%k_B{Cmj$~n3w^(2Ga|kwOAW`w&T{{@FJbw! zFZ|2O*VL*{; zN31r|dh{7Gb$`;LBdiH~L5@Ann#h79O52ni!HRfRo;srRUBpq=Aw;^h7U>I*D$=u$ zhWE}~t4gb5s!GZ+$m&^n{jmV`aWd~1YY3$Jk9?6sV9ZD$va)WT*=k z;Td$?T&o6!m(|Lk0IOOVbe2{tgB(sNrcACJFvKjI=-~vd7|53XqOai&MWW$xjH+VO z6r?sBXLrVBZrco_xsm}G4jJgSh{%y$Dp?b6+NYaoCk+V_xp;LRrwvl(cANsy@d#z- zP-6KGl&KBqg=I_rq%1v924GluIoXtIXaO11kjw3rti9qa7t57PGaIAb1BNF%!5SM@ z20o-QQ6~m}NhTQl$X!mr?QvF)JHc*JAOpQfC;R#R6Rgcu^^BJq!3a9dgSB#DPu3F$ zsF#6prv8%^oP3g9#n$;BKFREi?ejnNEj!BbocKNT1lu7W{eksmTV>u4uz0r0k{?(% zzSSl(s##(Lw2d88*5=$QJ5{kZwtWtlIhhZZ3BNFpe4>i|gYA{Os#vTw?{_kG{3olR zf953hDWYjcLBu5(W9dMIfRcf?!_TZQ zKWde$f584Lq8cjVsGL*H7P5V^$uDe|HB-m*-7m~a)vJFEVRD~l%Z+mR$!XTjy2I+R zJ4^jq4SSgCKK2{yZ{*4Kzp=+!%+H2!z$PX_)gF}`u?E>!onaHvXiF=D@Jf2u#D;AR8S_ z`m!7x+H%t$IDstR>z{L;t>m5x%pl!O#&Ds$Dwv9ZZy^mc1jBS4=lcv$wD$t20WO;& z?sAQHYo?Rk1xGO`>EUr;1a0`j3oy;q_<;DdeE{;Z+AM$oY~@9!%8>^({*3|FrGrfh zfo(0%nt3d2^M)4Qv?nC~9T$6Nh--GbJ6>?N`gW`hps*B)3hHnz1XU`B5Hy#MSa=5m z3;7d3VjQp#b@>*4dlQ}b@p{PwPXx+{N6A)xh0(DQddEhiWB3kWuw#kxbt_^%^1^!u za%8r(8;Iq#IYrd3>5E+6l7h(uF9|De`bZ=85*`bPt<``iL)~2niHR z+|cUft-v~Ba;8U6K#JOQIhC?9@QNo>U8Yejbat6JdX0Z7R453aK_0Y6J*G#2Nt;H2 zCiqyjj(ZFRN5hUYm_xj=)!_}k#A@;|=TA^$Q?Lp##S`;j;*_3=Edd#d+DH#?feOSw zybu!&?ty(CVhz{^V-svcZ*``PM0m8pG}uC5T7WJO7*1vo_!Xx!%qA*yk|8DF%)ODk zTlW%TC6PzB(ddZ_1v-B{rs3!&lD#myp#XXXS^8NdZvvLW-b{}`R0l;zf&C`Y3W71+ z>BH{JWtu*Xq=UFM-Gked0W7p1Q_QH11+8@~SZIxbgHOa5T=9&HKQ;{-oMc`}2Oj;v z3JT8yd@$96GmKEjNtjI`ISK2wk{J0)6mQAFfPyHV;v$x)ODBqN)J;q@y<=7-K#pjh z;;mDQ&V$GlM^%?O)fo~m9H%Pj865f>91n~VJ{c{_4Ut816rwdFg zS)^ga9nSA<@XZj{><}}Gqj5wAM-r^2{@NJ7sVw zvC`|fFaRb6fkwmx;8-W@uD`Wg9aN@z6pT|u#i?R> ze*@mM(=olzAZ|S*!EI8Kzuw`p(`7)Y6kSD-eNkO3^BV9b&8r=7yqKK7AOwYOs$%*O z11#cLv8-soTehwy@brhW$y~706eg1Gu834O10v~a$deMn01d{#K$nx%$iW>vQ-18^$?a!GIQM|@hL$FVK}(aa4b48T&$;F? z`kd<IkNHG1ZBvBecg>``}@Z79AnS`Tz5VH{>O~ESW3wS>{R_FbkSbmvTLBd3< zA$;dsQRn`A>`O89YDJ)`<&+?8P6>JjOO8>Z%qXE}u-Yj~R2U^*dI{F6rbMMtM9*No zbCjquO6VD^mi`G6HAV?NgVp9!NgDnTar6vUTSAEpD)FL-UV`;9gGDIGrUc~>gskwy za!ODRmE?pcR#Jj;s3bQ$v6d2)LnV27qPw0dpcG|M(faVjHcC(ql@zLkbj9(w*dltT z3@Rw4M3I~j#~0{uv9FiqQkHs$ReAXO4*9#{*ZP7tI^`cc_a_3B5uMW6+yC21G< z`!8|sTlKl`kB#SdaX6G7Z_cr=t&|H}@OSYTn82^IAsUMAugO1J@yq>X3EYB;@?auw zg8IKCa?WrvSksEX%oh5Wz-P@P)G3-eZ}XRVcu#`YAc;4LuT;B>WQtD4E~ArkG+7^3 zXQh8Y5`UVoZ)gh}RL9;-9&X29&`Ibk^OA9EF`NzwIy%VI6dvIp)t>L7Mmj|j6x|{- zJMy=5svcC8WL_ukK?ob@lYX>%gM|?(n|9{MItPh^-$f@5i>ZYoc#y0^GqNRUZYQtq z!oLpgAz{erdq`Lt{;Rt35$bRdc@%1i2Yo@2HmoRmN_x8U-;I{>dT{~Yz(>{g%-g_Ml;=hMB5@d%{p~CA0U72&*u{23y&!QJ<-2r z0B^*a>gDm+&7)cZRtGD9x-Ig)%Xtg=>p(sMyZTXs(39En*=Cby zE6VVI$G~ivid_2YX$xM48=0uZ{10EAw0q2M>Om*q*pM1Y84F# z`$X?y4F$N39m02a{unD8SWJ#B;p)Yc$fKcJs7OJRz{Q9pG=ldFJ5lFsIqnLD>5(h= zK(eI*~+w1)aiWwe!J;w&YZ zbH6-rCGTVmE}ctba61{Y)p96*v#~B6x`!2K6%?w3u%j7Q@%}W$u;H@H86$YS{OT%j zd-O0K3I5(Nj9(uvl+><}7_ns-KN52en8Ao5WTxq2xNbP#j);IKM_{bbyksQQz-(!~ ziYFu0`6|8uvvcEBd|^!K$HAtRG;WphmQnmhgL;xbP#8C8WLKGeob~k znQ%H)(1_V;+Q!4WM6Co^!Q`_rkKy;@c=Dk!ydS7|XAEx<^9DLh{(7_6jCe`zTrR&D z!zbdfrQcZG=ErIMSl$-Fs^5&|JrHl&VjO=FWoyRaIz^fsKAt~<1C@>A`Okp5`f5Im zRrzbK<_|C=@41$bY*a|RVs^wo?K)DP+0y$D-W*}J zOaH;U)kna=fAIJO9Y;k2J)DeCD4lJl7k{Jcc{at9t-66fjibht8~Jp$#{c?_P#NCh zWyYB}xEv!+1yc;EbCgm?;5hie?gey4jHEvgxbay&IG6KKK{OLtR8PfZl)ZwC6p<0g zKnHhW;mFpwL}FhUBlf*D58K}Imc2ur9TG$#?2 zhVN8Z%N6Z%#BKaX_MPl^JO9yI^COM~SIDjt`Ayc0pVa%}iTqk?uKs>cPCf4iquDyd-St|+F2Xf?{{FX4dV`R;pJUR^cm2%uadBZRaZRB(Rgd0}i(hZ8(cec+;`hd7{Y+g6kes1XvS6-jR(C0<(^cY)MSmnIiOXf)6yAcLdtH7yg|}mca@7=` zz;n|n>5)C}Fe7_oX>jQiUhI`}#{1!akdVr6{T-BWoBwGt_L3adSCDh!viGG;n& zB3Di2r#t3a_3tc)bHjxVo8X%Go7-U2LhCIR7P|uOoMK9@Ll-QrtS6!4i^^!QF z0NM1%laCRwJ6B(X%91YxI(dbT=UT)P9UXOK2h0RiyZ8!>FO zbOU38fhzYYzS1xY?RrTRN-!{F7H)cy-z2v`&0oLi^A8camn^EcLdU5?DOhKzLb*e^ z=!CO*Y_~90D?g!#LKoifh{xkMJSo_}Ko#Kp6YowqJ(88)LcGiwx%nC1BC={{py6_P zyO%dMpRq)>l!Y^Svxs_15?=K3_{i#yFKp97m7Jw1RxJwZDTz}h)jKY16RS#2)hPj%#WSccb@Hh%F{(v* zJta<6vbLU*hEyWQ&*BlV!-(}jFk>bR)cK(-f*mdMWy)6yiCMf&qugMAK&qq*pE*RaNGDEgzmNp0>Xq}^V6O;^MbTBc z?ZWD2nU)Swt5X65U7rPlvO4($iz`?q^^`EZ_jO7D>+5Iv286}s%!WEukH+%+Z0Ph~ zA&rhhqg3Z2I#&axMf4$? zK=|*rx=~!Ebu*6D%~(=5W4X$Rp^KVEh}T+`Bi(cPcMX3;9EK*;O+_Ftlr86R+3=@Y znVbDv=kdWTriOMlD)3*N!z-4qxCKg;4_JWx-&y&@0XNqp)>Y(c(}cSxQj2TI7x zH-5Y~2&?f}7JmsfVqW62n~;gXz_M%(xA{R8Dg~E=eCH*;1Ka#Zmhv&wZ3tp;KdJl~ z{(Vc)71a3kWq!3$gN6VV4QGhFIUDijU&tv*S~EHD73>#}p+{I7uz3~*h)=+v-usHa zq@oqYhvR`gzZ$iWl!)cXpI=9Iy z-r$cIFr9RMp&$Cw26f|`{94&+IrkdNtw}F7!wX}l<<=~lz7FaSyve&u%bR>`tct8q z&_yXBuC$osZOeK81nglc{?J&^?K+$&-J9bFngrG%3%?!fZ4Fl~pW?C5{TN!1)ujVk zmn{^9guhsSUy{q-!5zRk^58rCPPR*mclq@&j$V2fw3GLu@LlZFcgf@L@|NBz`sF~F zK-CDX#r7JX+QjA=W|I0)pDK9@4yt56pGCryz){Rd=qmg&I?f+(c#WF4ZjB?oD8$s^ zw=GbPBWSLU@AX(n>u?;utB5UYYA2IPeCWL@TE%Oj9VT6L$s(AP$|3?p`AaVE*4v_g zLlLJwgl`Icq=JsB@uv{Mi1>bsUI9em74woR;0JrNGL>|8#0Y6{n!NV|H4qDCK2qGp|TqUer{Jb$;q{_m^9IM#7u#p$7 z<_)eqs`ydK$n8VNZ*;koe$fR^OEQ%#%Iqd@g!*zSGF)c$RtSC)rR$l;CJ(RXgS-JA zKjnss22}j)D1Iu2JS(c7MfiOf&G>y7it;2(0VH%@TZwZ(VH$~_Y^I?ilAXT-km{kc zz)t+9uhW9T#vouhQRY2(N`nypp?7pN1|^KsA%3-%U##Jc`hJLO0r=KA!?p>}3Xo1? zuQ+gw)sI0RW;t&q?=~h3G#VO%2tt7~UJufAAySjLjG5@1L{HTVe7_o>=n(T47Sa`! zOp=b1R(Z$UFkUw2^Vq=!*v`>$pK`{~SfZCUkrO6Gx?tti$uWyUl_MX22kL*$#b*fA z%Z7J(Cw+b_wd(RI=d9u*+g*wv;sXppL2Qc)l>dbQ0`tVxSnZC=Wvls~$gmNWPpyH* zSHSeqVIRsgKVQST38yv`@Hrt^218j?1%g?va7Y5n`z)cI~ zouF%XrNA#+$MYO{pKQa)xD#8i$~U!ug!s?8mXma#`lbh&?AO-iJ-wWIZ3(C9QZH&UdJ~#ieGM zbB%@e^GrO1FZpn@nPID`i6X+T5%w3>bI~em*$x%=;xbcsFoi2G3Fc6xU)J+M9Wr0u zVWKc7y^BmdMe~j#j7`qx;6$ahOclYJx%GWMs?jHeBZf%PcR?asZg@XHZoeKsQ89HD z^HiraUv-&@CKTgXotYJY#= zLp~&KE$v5@2Mlp9Vw+0I?uERE0otxF;{mVplZAX867Y2T()|a z%Z?vGS1V{elHhECySIiS^OHn2#q28|Y4#qaHj2NZ40#-Q*?!r02X{pqCFOd_kR4b7 zkH~v>z-Yu5FLo%4FscYH1$^A2h&N+r{i#K~14HtKk6|^QmHvzk;7|$2;wjmrTpDGg&z+21jK82}N zBu{;YBcDBTz~>O6B02GMeh(f+pYuPuoLU+fQU`)#&(%s5zigBV3L@06K+9iC_|MkT zEGm&d?BZ>rkKrAjgZVEZ>!ft==940_tR&BHGVGC=yZIUn{uO(`z#{p;9=<0GB_b)p zP?FobAc)cgl*@HA(@Oa+Yw^2qI;zjZPJ^Rhj?EFZc(1P{oE2)1pKuMM^XK zeUzzYbn2i|3PH3hP*YAX=S$*N)~csc1v23PJfk!G{SUyTwVt9HOXc>1JgG|oy{nl= zIErhvRVjtT?rI>)RZZFK5XAjeIs6d6KW;u{eL!KdRuEC8i1!yAq8~xg&71^MY#v&F zpN!1?DD$BODIDXQzv!ZPu=`cI#0km`HkFpg1?GK>PehW zJ@2nL$(!@IZJXc{Qv*uNgi0022H){#<4S9ls8oSm@g0V6k^iIbpiQhx;8nvAj`#sX zc#LYRA*2(J>R?-hJL@Smgk%S&Q>zs+`v?AM;#^FAoY-NTVb}M#Q5Zz76au1s<^4sx zsef4&_!gS~kw5W6wY5_`X(uihSMvnf>}UQuy6FCex0Z)~#vasoZ&w|zr_!sH4nZv$ zzhwVrwN|<#w80$zTvn0}Y!gd<;eorjPH29$71Fm?DZla~#wICVCp!U}j84MW{)SD` zqo*NFKgqr|JmWIjt65zUbUFa5B@oxH(Km#35z140GMd+f^M@MVm2H#m-?-O65af$O z;0J<1j4k#5dYVfZ8Mb(xReSOx#J#|@nlQ-<5hq{c8c9|m z*Fust#H`hpEOQtUWU(odlw{Et>vSUgFPgR7Fo79n)!u^`z$4Jw@3LtJ!-}j9?OhbX zh0t1-IkbOA)_hCOwZ|cX+0y0In!@eX$EjU;L4Lb4mS~8r?m@N$+{fvs0<8gLDuC3; z?M|%?fPCxJIyG8yVR8Eytqs8mVF3^?Ux*YlpD z4TG4DEb7f~vOy!QH!nOThd0s$TOyxpq&?JTEf#m3_8{7NXmrJDZ7pXkh$WDP4YX#B zs_J&*H~DC+)*8KB8mnFBsKKV~E}%@8HL+Ssi!hFUUPD?ddoJnm_zy?enp{Qu)qBmZ)I&ivnw&ly?o_?(H;CN|kan!(hc zO~nKICPqJH<$PC8ZLCdX^W?6^+N18BSZ9*?VET<7hWHEaEVDo}l07AgGsp~(lbdM0 zn&|IJFH-DA0Mgnf+5td%zNz+jqaY+&&vE;}S>{iOhgkw)Nj$8z;(x$T(oBnwTQX-e zW=jqO5XfdWJ=5jfW?J)(6$GF5Iw5SZNb96d=~R8*Oq;4#sfrV|E-hQD4nQNRF=Bo2zz3XznTkAX~!~sX(09h0B=uAT)R*Zl@OXrok ztOuNw(FM%&m;}yebxsx1S@X3X?a97*+d(?H9lE57B6?p*6wDw&)p;GnRJXaUwMIAm z+qBl`TzE`ttX^m3q}JLMc)Zt%et3g``_WrXzS)>``{oLH+MDH=|8mpCSSLP*YF96T5Hkf~Bz1s^H{4zSKK@ie|(Y~rxFR-y`aaHUjJjU=ou^b?T-)c>~0TENN+np&76D4CV4 z{X2FZELJ+GilFO4bQFz~j=}AT!~V(bwX0bC{Eu+OD8+;TyJ>Jd!riO?5Y&9RvxC;U zdGH=1PQDer#{%Y_?AlTD$o3tz9WWJt?5Ks@`e~iC4IOHORX!g2eW_qJ$4>#miX)rx zt`x09=WWoWDW*R96ouTWz(V6}19Ov(bm&SG{Pg5@vdVFnX%EPbmuU{ew*gNO)iUd~ z<@4*7AYQ7}~jVQD>~pXXU!ikgK`!x6T@Q46t|agw%*GDuqq^kdVC|+OO|M zm85Q}%CK(QgGjxnr^>o%^*RyM20ucc@2>rUFLwRWLmSB8$r#W}yT)3+7^AtuzoeJe zidl>G#QVLGXu5I{hTDldn3$*q^j<)vGvp6_w1@Z}vwXUT)>J;x7gpw%@^oMAYd8)L z^wX{cU{C)L;3xWPS`hH80otG-;0W3ih664esC9^{QF4N_3JVfiNyj8dmOlMMf1iVe_uh5=p zN%{r{E);)Y#`;RpwfL47=0dg7A6IJk({Q2{g+byGIIcqD`{dxEnpF=k9o?V^*P6vX z1gukNQ>Ciy$oqVmOr2X?f#tEdz`6k>OfLe(qg=!x7qTZ1^(6 z{w>GODDaM{r3_s76U6{@S3i2#hFs&dVig7H_aSlb#k=6~n;bAoivbnj->C@9%|_?Dqo9KHOvLQ-5S&tP>p>CYdn&0y97N~}N> zs`fXoatWOW+0XeZ8h4qmM_L^$a8SA*+w z<(O+|Li!)P209waCD*F?`QEkKeMq&Qpi)C8Xye2l8x#jL3;7mk9N+?Luib!?9P&R?eGyHWGtBcZmNw7v+) z6*p-EprxLpp}pHGGIl{>W6xDG$=&R~}RlRGsB>y@?AXe_G!t>EWU zhHg^e_W|5kUOwv1Pz(zefWCdW{)RFGHwVZy>+SO+>D6#{uIQZarx@;5}f^#6)X^K46 z&so8asuy|oZtb>iItSs2#d;r)54J*2s?UJ}il}^xIEM`Yfrg=gV+Vve%X#-`&$Ib5 zakAF5MR2{P)g7wcxq?Cp$Q1iRj-RZxzk^zBXD=7DsVSV(LB0+Nq1Gd5K0^sfc+)A5y}?hEF`lYIpQ#- zX%B<$RpQ+_7k&rIqc5FejWF`?m7b5MXyYL3&F<6o)SiD5vfjbp`hM*$)_AMU;~1yY zOpaz<-}tj1(2^NGWU>80?K$x*u86wmZZ|F_&x~+0GP?L+2wY@zF*4ckkprLsN!V@b_Yp~X={JUn09wU3yu!Lh zgV_fn^m|#Tca?ryDsY1;ydut{DdL`bqkzzH*Xd1Jy2|DLElH<^nC=ZP=W6wta(^VXFto{)3G(mmiva8TUqInKEiXJn69O; z)BfD)T0`C(MiZ=j{O~J1%oNV8PCpSwDtA4qO~YyK6^~&@lPMp5OuNsy-GZ*rKU7n& zes~NkaE*j@*VI4eas23C!0cQ2FEab&x_@csVP>v-LVE|Pe?A#9{wki-x(1BDrcY_3 zS=<_YiZ8V@11B^0BA2f3ZCOk56k4v1sGA#L65P8YksculD9>}H`#QSHdcSnj==#YJ{G7BFx9hM#-?lC*l+$}>13bl-y`%-c~%?1_3sO+ z#S}N7^zTBd!;(!KK~hWOLy@w0j`nca=MY0x<+T}FdH~{q4A?jNz$PJH{Om9@##A<* z2MwAdqvvDs&y+8XFek|=^R`&5m=YdNGD=^} z)Do@psme^5l&K_XLZ;TW9Z*{%p&RMUoQw0Tv{48zLQIJBxISiSh0rCSV`ZjhWA>%r zL93hLH~nC-);_M{ICQ=Gmi_?R%#ufS6TjmLz5B|d@tt}q=4 z1b5P@1oSahK2*ZAwL|1-_L4b|DU6Ssc$Z*z`rh-9$e-kVpLUt->eFu0-=D@KVu^NJ z(?4l@UH2Sd(oey@Jpr8fI5cID*&}K|c`)ohuM&y*sDdq;?FD80Vu2bhpLs!h>cUm3 zhrj=e*sC=@YOQaTS|T;h5K|(vv=g{wHsd9&F-KIvt=ZamdHiMV5&iu=h)7|QxvA{< ziuQS2hQH7_Bc%nk<~>Tu2FtYN^g{{i=P(@ffL(^w5ML05nwFm|(>B98Uht}NvAp@J zwi1U3D{^ok{YVZraQK;s9L>iXRU!(9qRF9uNgOnhC`Z4pb@!&xCpRH~IM^37C>s|S z(zxQH#$ZYoP?Ayda!O`q29kp)`5u)b-qIE|kdmt?iD)!i)BsApNy!LG_NU~sU}--} zzDP;Cmx}vRdNHLfly^3AQlr9Vwx1;2yV6rVGKcJ+7)rOMmgUKXH`YEY~sWm0v z`+uyx34Bdg*FTozI%unNi_X=z?W0XX5JU~dG6X?L z5CqX1q(qAvqJor^DB4goZM9WWN$dYz``mkz7@p^OfB(1j$vJzx`|M%uwZ3cZwSB=T z4rXvr|1iKUKWl?87!imiX079}t{Rsz`&nyz$+!jxkRJzi)%7{J+85MU1uyUgaYGy~ za`FY?_tDQv;h?Tr-+a8nm&%vGTFViPwyUnq;bokxn+bQKe%2CSklm?Ui+#ah4ld%L zZdQ$o!Ri%*xE85=W;k$!?*U&`Riimv_7PP$INw(_OfLPb*}h<94wfwem|pr>lQ>m> zqQ2yFf-k5~L&b4We-fkxKWnTn$TZLTXIeJqpPo&i_qbsVYt+sS0SY_@2X!ipwH(a7 z`dQPs2L0KH1FiD?98ft=mRY_mh{L+_WdTd*$uiHErHvK`=J@ikIC0}IA+GF~+$k%} zQ4V19!7I(t!G()KqV)a=!em|6AzHZ7d|2h#?^jov9bhfjdX*Uxl@b7Y4!Xs5qh@4P z-do@k1(FzwW+$Pd1@y`)vjqG23#(zebC8TQ^C3JQNi&Dxu_4WDq)OT3D1}a@nf0nC z9A}aSzZ^``I^mH|fosgL;AF&Whuh5UTSfmxiCGm&BpmyXzY(6{En(##x0T05PV+wL zWLS0<`L8v{Hh>A0)26K)k4=%4FqYRMN*hnnnzd$vf7UY80ViK%tpl4-K>u22whR~t z+f~*H6j1s)b5!Kq<;cS$9|5z_K2eGvJs8@Td_R)HZ+1;LpR5ad{%_K|(9h}Ey$k5i zbhGKOjAZUWW(v3gJ}!X`eSufT;|J|-#NKWBZao9rQa;2RRaqL_OV}a$V7=J~KlH_V zb9Cn%{=OEd7JXn9b0Co`*NOygKHoE-^|Yl{`R*vm?_mEI6Ihih=8!fLUW{p zT11I@bl*k*OeJ)9BlJ%2#Ge7qcQd`1VX_l}X&GiGAohDQ%;x&C888)mIuf7B8nH|; zRbb6=X&tLP9W!W>kmM4LM| zjD+Df@XjdS*wJZhFkk;mbV>o;|E0MKN|4{bgxX^dh3y0zvWsTzG<(!3&^1G|1Djqzx?5AD2N z;@A72(6JLyPu>0Ivt^-q`!P0$X=Dz{AEvfB7(s8yO*vp5jhXcO0rP_vrQdRg;51IRG7V)~OJPJ1REUU7x=Yp2lIt(`d z3}qZP$D&I+9x;bw+~yuJ!!0Zh8Y$-hYUfd1{w`hD>D2}v9uXVPxW&y9YDKncu zrP*rZ;v*P=ee`Oc846>d2hEu{jTG!~dcuj+zP4H)Z1OCP>>*Yt=XFT{C=5 zU?7Q`kyk#3n`-U!##lJ{flud179Us@tu@`)QvkC`>-193_k8L!R5ZPK%#4g08vv-_ zM&FHsYqGr9MCvi~t{2A!u)9Lj>#h(s&n}=%28$%{RmNzOaP%nuKT>Rz3DgWA2s+OL zO|b7ZQHIWddk0)jFf zLEh-#tAPOs{=?G-8W?ug#aIkG#qv37gDETbsCLu_=Ws}YhqyZ5nvrmD#>WW^$XoaV zhW({$EBk;I-p6W#eS~;G5#Y zdh2~_j2`JwebydLHv5KRQ;P6w=IYOI5$DrW(vHVDZf$3TB%U92@i)%>$8ocV0gvPD z3e1oGGZAvwM9ATqMg;{RLer?tNplh&TTYsbgKffN+ngGfha|oB9q8&>ShSj-wpoHv z)`zXx$^~2WO;#?f&<8@th%PqcwG@BKyina&ikS=^kbD|<+MHj`pr!j6^NzY@RwzK` ztRhWlP#@+q8K=!!wCIdk`Q9wuf|l^Y?gyri8^d+F=JBN0=$65|eFBC=@A|w$!&v7= zo0VVBVB5Tt{cZ3lX+AZeXZQG&NPlbfQp|8pi3sTF_fRO(EyEj~<{th778MT0Cl&$$ zT0>cdP@$$$i5&_(YlfnyI-bSGww|6mYYqv@;My8l1$ba5-+b0=ZmLDwi zj>`74<4QTsX~)HAhpxb75)fC#6Q@B;c$nk3P{d&t`+kb|%|hjHMjIdFcwDaE$SBbe zbDyacZTr>a9sKOCFyz@lwJw?a08*T}1fFm)HUG_wue%uJj~xv=*o`~pA1DT9pv9Wm zL%)NM_~$pXI*L^L-Fz`LM=OxqfuYfPD`cMWyXK`(W`MDg!v6q5I+X~aLjY4!ddAAvSRRYff`rMg+N`_Up2?$uE~zYur1M{e(t1V^N10>Rs}}!ydZJ6kaaY&cmTSJwP^2nbk=X7DP5Y=gn`XFks= zixy}ZqWz*OVYn+{!6pXi3(M}M->;c9!{)*RF;2HdvfJRmp2nD{%7cU84hFHXRG&+Y zN}#2Up$AILPEKwR+Cq~{%(uAl;2?BsgZyyb5WG@mEYh>Vv)GK1Wd8*o-8K9d@MeUD zC68q-Hf+SK3{V1PQK*S!ZYlx(?7s zrDoIG1*p(fge2=c=WJmWal}Q+Dg|%5)_tzj{JxwCjN>g0UxFrSWfz_P$GlQ6hHc~* zFsU>!k$KmH0@b>-hhypY>*n;(ysO!MRvRm>80^ztzL^|WDAp_vrEFR#f{jke`kfod zHn$nR5VWz@PG6`}1mCz5_&_Mkk@IvcT`8-uA&z@aCK)9Aqbo#7lTIu8VBHQgU4}7LO*OVv4bvHiqIulj&%v7*`A8zsXy&$r!*`R*7gV z;Ej5sR`X;hxCk&BCd2_(iW90LUntob8B{Jr>*@(y0!~%xi-Lwbr`l3JE`plEZyq$5 zukyq4%Rwqs0#(99-RQV~n=?V@v=@itmeM~jkBX=P^YUdl0kaBaAz=TV{n}Uss1`1K z@S))&bPKJ^{6m@;RDc=sXm^-s2sQUlVM1H+g^POrY0FVsxe};#xVWPw0~)SIs0$LX z$xIE7FLMvFn1wgcZ$?tI4P60E2^UQvWMzbl2DR3KB|&n_C>V|4Mq5`YXe!p+&*7qT z^h!P&$2VC+5`%RE{1)h#M7-#jRPPHQARW=r^Tf#g!l$10;HWKLxPDiEtR}p`p(2|m zc@Use{tUjAMXy|ek80>bG&r}K{2|r>j$**k+xklpqFx{sv;IsxzZwZZQBo2bb>fc!0R}GdAkPagJ>{j!xzpSws;qW2o=xObd~K zl6SNhVU*BP49EN0_TowE(@I1H&&649c7DfOglQ#!1_24^)FRirDV-L1q1 zrm-KkwrT8LZNxm7NFQh;-p6CmAkn~4uz*Ik75Dl7t?vo$nLs-RiO1d5?-ZR35QA=a zi)Ns9)GjyJS(&p5I= zi+jE8oX+hW<__#6?)0?tg&PW-zGZ=noqYvbQr~;`#tn4u&P!3=>vPu5<3S12Cg+82RFH^zI;WFN;)L2ZZ3{IQ3{{b*tMBjTPK zbK~>;?(lv~kw1sQ4asF)eV!{Peci7gFW2JL$k zbl?cJ7%I~Es>5%GY8IuGA6F^-F)<`o*Ix$k(@(LB9aILDAji@M#gw>jZbDVIa#4lLM)+Co85W z6V>idVZMAqGoI2U-SxC+2_oM0X+4*od0H%KpAL=~{RJ*6gLz~4MJabM5V3l~?&Ksr zVYQc@tM2yCU^mc`c%;KK6R>fWlfwO33XgBW$ zn8xdA-m@Y#92#z>>zFHeR0aaXTfXC6wjS3YKF1TyJ?}X%TfwP%vNJo+ zC$|gTn%r-HUa&Cs)C=NGz_ee#AUfMc1foE-k3K&+rH@}r;C(rUF1BA3Z7;yN@;8Zu$=$AzwJhr_I8t22b z!(I`MDnY33VZlZxl}EcbvnF|(@2f6I(y8_Xa)n&Od9>2HZJH68I_CiC7B zb8HG7VP``QnC7gYkKPtTq0{^3ZE@I@qcwEsawI~)nMLk*L`01rnPFr8*T=BM(8YJq z4L?)OcST=_s?WSDVmqD+2!)om3WPD~+Nn=-6{}W$PTK;GQP(nj3YlER&M3I1g>RwS zqp_c?p?;%9512ts8I1+Fn@*1wo!j^zEOblx;*6u0PxFST-+Q8inxw$06wrkCFuG|} zZIr4N7Na!#2g%0!!uRAE>=Bog@e9!Rf|`JJ)99c6;hUS1_@66- z;N0Rv(Skc;afX1gf^mlt!mPIyN*{eF!m1~s4puH>F?7I1Stcm|nh!rGN&Bk=g=BN1!;hq({u1zt3k7YNUNv|EykCc%IV?nN@}dp1}U%;UtZv?5Nt4p6)1cyU+oN`=EgqMRWZ4u#XO@!}a{ z6=jWw^tY1EjK}UVjf@H6O|c5u=~BK5M#SU^V#>fW!tS_%uxo1PqvM*Y`w;YExUgYY zU)ko!C=*yFk03^KIXyp7+*N(K<}>P9h6X-#eCkATXB5Y?st=?JvNYr!S0)r$t^DdB znq>);FP$jb2k+yp`8*7#+4-n0;yOq7#$#V8p_k%Cvzp(rD_hWFX!O2g@`t>z>`#st z1MZ)@#M^%m?{I??v#$0VHa}kbtQy23wpm)H2eI5L`_~Y(4A;p3*LT!u5*U>ddUBEo z5AcK`PC#PHI*)Aj43`?7bM+14Z3at? zT^rr*M_P_!k;}U2H!^&`;j5z5)6O^zblB}Yfp+%0O%=($D)ix2Oua!+YuT1Cdq4^- zG#3^m^@*p;9)SYh%0R=BbC2-kY&2c8!L5_}SSPk!JqeJG z`s|wCm@Zo2SY+-}QH$137mZ%_2_IaA=H(Li^Pt+hEru|c=OmYpN4)2!5;%+I1oQD` zHOBQNh+s4nPH7QQ2QHqx5xT8csp|}ImT=xP155!vC2OW&?~&JL3ce?P>Zf8j2;eWD zibi2+%+|SBi7l)*M|eEI)rLc1N$5Y%t&K6gU`xBG!)gFH{aLT};EM`9Wa6=($q;&}VMKed`j%En# zq0m_&_)wgNIL(VIfs4et8_q>%flC-N58d+{70wfVqDxofhqiKUOb`>&JRz%a6((N; ztB8}i6Y_=Ov5STF*5Lq(flcamryVeNMnoFu72jzGtyEw&AS5x|v-g$-U*T-rUlm-S zM)2_fJvl;K=8Mq(c=7=`J?9>DA-*ZV(Zj3sj?lQS!>jgYLwl{U#iYC8%mcdI``Z=I zJlIDbhWd2TAie3zHv6dzh zCQcXw-Q6YhZKAjwoR$UMhZaV7MkVSHomnV`G|Ta(@cAq&%NydEhZ7Kb0v2#&7CpI0 zjI4c*&y}&g6$H3hd@?P86JzP*B9N%5bajzv=EA0>k40iVG8+09wOK5dhGytJz}mx< zU#~e(JS$)CJ@oTplpaUUB+*x$x1%0S5(_l3W9pqQ85B7U4)PF*CF02^ZD=MQRM522 zuqrWy?Wogw4=h3yWK=JH12PAK$cNDx(7{1c{6*QaQhLusQ7%MVmgsHs#1eoQpVGA@ zq7_4m_r2O#Bw)Ic!*%i;w$~IwTABZFDJFtb=`3(sI!CJ@7&*1_7CDwLXI41Ek`rvT21rS++>O)E+fRqy^;<5cmAol-lH2{|MKbgIt!wjE#7efLU$5h1Aod?ZLP1dgeN&SmALAFeTXtrqiC z!DTdmt9#vQk>#ic9u-%`Vz)ZK2_Kq5bvB9tcjfDM-k9JO z$lAjpO>4DzC+^p=E^XKW+7W^`PzzlDYNgY>jiP>JA(zp)TvkB_b}=X4g3Xqf)@cM? zXX)5R@l+x$>w_2H2sKG%`cn>G)gA0@v>^MMfM6(85K=EWA&jjglJv zu&s^Qb^P`@NWcvS5W3Kz_&v?jIYM1AmGmpFGe5gYJZ99ffkEKOn%%W=B%JBM*}g~J z;<3gt6F_-c{pm_FfS_DL(7Fo|kf@R;;ynj{uw~@AMGe#V-hFo|Rf4P>^N{vJ2B3*5_;_IxOzFoDMF`jDwF%2h62Dz|! zazHZB>IcB7+orrU7ak$QiNWM1QPJu%<&RW%*)pdp%?-s9B zEE3MxT(u~X8a|CMS80MIq_QRS`m0D^OM9=1@&Es;=tC#|5jy8nU@PI}6l_{M&F4XduYHnW zzXOegXU%JvkAKqtT!R{*gsPSZ_6yV?g$cR1iZ>=I02WE{v|pfw@pMth5ynM&M9Qup9-m6-As&x{A!(=N1eW->IwfED zSn8BrfCF^$mt!5^dAC-QKj5)AP(B43^LL<}*{cl4&Ve!MOq@Xyuko=~`v^ID_1r$)4SedKJ)%L9zv`Ic5aO;K~eYJM{IKNLU{v z*`&T*71`ccN+YVs#}N9mifm8^Z9@0;z`BKLxpu(G7P~l*O4qB%cl!RBto19FgK3@9 z`okB*xIzoy2|5G8@Hl#C%RB~-oK_B|(qg@{I=NbFF>S3X>sQZT&eaV^20R|aV-a1f zDj&Nu$&>Y_VxIVno6EiHLa&ddO)lxi$h=lf{@sJ`wSK@>fB3m-z&Z=cLfiHk5ViM^ zz3H`o2MeL?qTyQu=2ZMjtE$URO~z{5cii)>Q=@<%+WAJnu_Fwkq3Xs)?HW%3HDse| zj7j7EB5X+WLS0E79Mkut*bfvR(hj`Z1TWoe8N~8(R)h)rof?lEo=bQu%!;W z4E9spA*kO?k9D?S$s2btDabmu zi)4;jK=0I)U$Or7o?5acKS$J(9hw#JL31CZQ&c|W6|+lqB<-yw2l^MrVS$^jQxslX z*7mPsGcR?hTW#5>R>B0$Y4MB!f!0=>4yz7*P+NwDk+GC-bK8n~eX zoP(7`t{_>PF1M5+FTt=32S9C8GXU`*Y&yncY6d$5CUu<0HZ}8u&dm-(?1P0FZmhOV z&G`42ma$#EmejHnvw5v#;rE!W*w#G)Y z3l|W}UBT(=F)UgvXA?Lb%A!km$jL#rODQXxGhC#JZBRCeK5v7aD~TGnl~K(~cOk__ zx2)vt&_e?-uxh>stU=$(!B(z;Q1x3$^j2H>V0dyivb6H^!`8sZPuS85zj#bqc0Kfc zTe-qxE{3xstad?nf+m!>6Ym631Zh8cm*m@j`n8kot3V1j*+RkNR%dEE*`=xmnj%DJ zKW5j?ub^Y?WGmx4lI`XAx-)@upg*u?_+nHW+~9jNKys4X%a>F!!xLNGt`2fO+@W7V ze|d1>0859mXj@0w7+SRt?v{~t)@YMM7ivnhnd(wT8kw$vc2Q4C*91KqXnX zvm6Sw+jpI0?dsQA{K(b70>&kVIj04kWzz=mI0SqIuC6esu5><>A~atG4#;r*20akY zX*_uMfBDI4hfpQERCaxPKcfgYBt-)X^_PO^BmT7R}b`_ICPj@y6 zD+@6VN%p1j31MHzD#Ap9x@8t8?{&K$l~s)DMPKazX$;}{!Z3wl{YA%yViUQHcn{#g zQVV`#C&w(HpvUC>Kph`>Opf98!SHh=dW@wNEHzA{vyaL5s_bDp&rbIaqtHcq^>KL* z24%(LG7*nnPsq{1#c-|c{QwxgXcrok^Ms6i+;@=(<}yy4m10q$!ILDGsG|q}kMV)W zOXX)8rs=@CHLR;KyLhYA_jLd!!UZ7Uj8Ouo*bQr9ED~XA8$kCxDZ?EHcGAmF%2*tD zx$q>W$|R~XOm_C?OGCJfd+;zGuv7H$Q?j;E;GXl8OyL3RHXPBDY1DAZTDS?r<#PDG zX!)%Covr7>pNE2eGFi{d$MIP3yljHUm(OGS%y1VyFQpNj#(;oLozVI$9dgSTWeQ(! zx#lGq=J9uksoV)G4rKNVrhq`6YFd14_W74&;~FpyU}X<)BJKE3Ct#bAFUy*>I03f4 zto7oTh$vqD6R7{oGD=@*2F8SuEH2DsT-RSf6JM5*4NF%rI}m|5HgsS(M(|AVsFiY4 z(DP#{=Vk0-0B9?rexCIaMnomxvroMuA7$JY8;>U*x(CGXdPVl+>@d0VX6NXTSLI5u z`)x-6b~^s5eAIrAs97eC`jv^J^wJ1-mYDBb}dM&*$P9&9x?RL|{jg*?RjYAI2LJ21hvg zhx#D7Qb)4~9swOqI4$7c@$YE9&u`Xt0|!0QxC-3N%rjRMEC)4u(q@oTb6lM*Jc zO=0`aGgWsj^h6k>j%EZBFceuh9u5<(_}64xRK4Xj*{DpXdJUE@bnP`c4@+>? z>mZIA#2k&s#5ZK`p0mE!(sULcw&ZM;~JvDeptoW8TDaE}`T%<-P|%@VM1r2=D;3&xjmj0Tym{@bKd7S&J90=F6i@ zUWht3U*m{El~D*d5a{IQw`6E7JB0o)&)Onhv5zWWLTdWR%35)C!cVH$4_tgpr5r8Se7p=E&T6Iyk=PXpEo?mu=GDW z3?CwH!-_SmAAF_%HmoUzRmYqE7sEQ`hkxGi3BziI0^Z=A);u^t^951(n{tH{Kz8(r z0{xL|3`_s>mc=g8^PHdci?4Kuh1!#S!DiN1hSk-Zd!k|OHK4!qbkTK?LD+v_|EV=v zE_tAIA|{rm!K}+l@EI>jz7>}*8DLEb9!6huB??(wGnBL&i4B{ZKxu(*6K>OQDYc z0;e&7e*BkY=fy!|wYchant26)h*>@gp96Gok7k z0k#{*uI=sG(ZkBKk0A14?g%)RQhYj8vrk|xT-Wrqh)|=$jUltIxZxCnT3!xqjzRw4 zsU${@3e^xC7FIe04`Qt`Uhr4j)Q^potk&2P3pnXh`ZgA_0r0o6@-^?_G@aX4uIB15 zr&(jseTDS-SZql@(97fGkfv#%0e(CR{xH(OI5X>D16|N&V2B(+M2RAP8wi~_KlYVD0-s2yGiahAV$(PCqR4hj9{S*c2%e|lM|T#tPI@n z8#*;n)(lG0neDh#GU8>e=y;A|hbPE39q+EoCR=Y|p6KRrO+|Ugf>SJ|ZkQpwIz;K>4xseG0#oP|wOxILaMjzH+T%T<%Xc|46trgXF~Xf8*gCN7ptN8;ty zS{2Yt21TH;aIK`|N#Jf*(N~k?%!YYTjoEyrS8<0m%8QC|Wvc+GU^hOREZf{lW4L{? zZ1<8!iKp{xC0-F1(sNl?RS#8_)vc9+Abc_2pY{A0#4e3wvzE}hl@jvtDe`URZ$XxC z@J@YdiX7=l@naT;B}1F@eL6wTFmmZq0^qU&N}VdZ!7%#Asq(stu_6AVPax0zPPy~t z6fp8NrprKZn(pu!QW+}I<_TNOlmiWQTBAtr=uc%jFa0*NCk*RxiZ_5IUof#1l6I)IWo?hf+L&*=R%5DM=5hduq>>k%~0{Knfj>^wPu&ve)yK*JWuryP4%(AEVY zHEZb10xfxgKs-s$CW3ojO&=u6AF6(#r360L$@8IvMlO_dT6zv8v(T)M16Mee?8gA7 z1`PD^V`{ZX)(MHx=GT=Y!F{5EQGDM4qk)O^^dec$cl=nIfJpiHu^JpCEPeb~S#xRb zA~Z3Ewk?wFdU=i?+X`u3>ZnoU7ZL0~$#Z1bV21IABg0IrbYC5y_KRg-$8|+9i{+hn z-~;tE0a+@iw1Mo*N*l0PXs%CbV_<%tSu9@&o0|oS+tJF!!`?Dtwj!c|6|W=c`6RGE zF*G|#9#FHGecI}NWr=KKIFB=glAlD2m&%%5PjcV{{^geBhc=J;OIWcoD)qU=0snJVAKl3bFC zc@ADKRW9?M?W}AAaJa}45DWAIZ?BY{@B6<2-01g}az74cZCfRW1WkwSpmn!Zst+2w z>#dfvyq7;>=e0*glO^}gG`Y&CUU-z57}mDq!L0Ufidiee)MdnDPA0FFmx3=(z`N#< zz}H%FHoKC#P7XIh>6sr@sH1QK&6uphqBWPYcOn{~9Up4HcDp&KUDav7cH23q-4ANN zcA35)%v%B5aFFd=Dr>)XD||ui*KP?1bnaCz)sP4Ltlv1O-7!Mhfcg;rJvp`=12_R=K1Nc21Yq(Q}!tYfS_JoOXl`XNFuxGUt^iOg0=@$G{9DTM$_HY!h zq~a~|VaJy%=(l1(l$+?~tpINp(2lKgYfwfUNO60s2oLakld_-_D4~$gvGDcdF6#e| z41igbT!uZa{Wkfqv7aVy1JoKvZS!PJI=BtQ8+ISti~=BcLB=ikY$ zl(Ag~GuXFpyBx#MKH0MAZ8LArwljZ|4Y@F%b_7654cQ^@=7JCH0F;=>Kg=i54(^aO zp&>oHL#{SBb>^3{J3o(nDHpVjpN;SGuzE%8&;Sf0mQZ<4@A52U;W^DbKyvPZq4f@;^R{vv}CdL{Apu23E8b?e;b% zjt1+{;;Y^BX-M(=+pa|&jk#~dGvKv*4gq= z2ILM+A}*GXWkXy)>(}y8Cb$Hthw^gyXj?4*%NGTwT=2o^3qFTmwPn6>tn~Lb#8zX) zmyfb_(o@Sv1?X1HEFV<~t*8P9+|MF!G>!a9)(=SJAm7gHp7E8OY8aUmzE}29Y4$mv z*Y?WBj@{dE|1Hdezt~3G_sTm}4jY7Qp{sjk-+Fr(RW~$x0cHj#_V^$lI4+2<%V^j> zSsL^Y8y>W?GS*_jed&I2zie&Dyk~P#EGNz7U<<2|BQCn@ z9Rz)Vpwc}T+8azJTvEXZCgvlE`bS4(V_KIh8&uI&fB-ttNeqgM&ztA&vtWrD}zCS7-ydi4OQ5mI5`A1gJrK6}No}9<9OD4bxp6pzC zhZBQ@z1ZP`@_Y3$nGm#|H^e{~fPU%cT2Bj#q`#8_8#nkzP98hgs zfL2Y|_gZ0EB+}|`ssnv}0+Qfj_cteGlmliy#V6&)+iVE~nWhJwl27949&rkDNxQtz zJPqt~wYWwBt#549mLB_p;6Za~&JM*LApl0QmWXe-x%{7voNQ=CWGBbX_9r2gzsT zV}Fouh9<{hyUD`26{}zz=zdcxjw2Xi`-v`{kRk4dh4NpHs4~k*tk`mvldQe8(`d&z zF!$5w?{o4AUT~m(thd6$tG62YqkOqT;Wpl_nTE8)nI~VM;RvfN1;AjQF9mqv&TZs> z9tczh^*AqQJ$|`N7p3)5_O@a)^YiO@=G=k(S8`5lDD-;}=Si+1V(Ny~uwlIw3S;7#pr7E*T3wJ21#Q)bFRTP4Vmzl_ke`Gwip}co2)_rSWM~u&??FT0 zT9fX&C`aOW{^E;rck7&)=(rUs!hqs|mEzC~z%L@7O#-RoK&-jh$?k|3p{bbN)|43e8F%GEGCg6f% zxeLZG?$dt&?}+eh8^wCt0BDN+YbV~VNb5XDU35?R6SKem>2t6e!^gM|YgGhS2&oUl z6eZvYV(k?f9hAd3e>1CC8wxW<=BOGuY3BBiQRn$YSEKd?R7f21uc2RB> z6-rT6RI{j^>ATCS*y9P@Tt(GfPm-=8C!G#fQCA?K@2;xugkkVsRaKi?8uZ`eQg_w% zNaI?r(ZYDH7RG6UOZ5iOvEQY7HQcreYrLv`-w(u}tsGH(#hdWN-oY+r5 zstqfJ6BL8Q%w$=K91KJ-kTwRZT{bZHHGN!D?eV_%uchL_?SE5CwUxYBcT?E!va!2u zZFRrHo9E*?YPa{jUtP7fZ0b^tP<5~4%r<%=RJ9DhxDAXIFZUe0@GAL}BeDxtGML^Jb0~$rsIOWYS@dgt^<-35))#tW z>D?2~h`|Z&-nCbZ&cN0@3Aouf}rRL0`5Azgnf z&OS(jilY02Msg7KKr_p_8XdF}>?}CP$mT0xU0v1upxTL$a8KCL^!KLQD{{J>8PYp4 zd25HP6Ubii=(TXw-BFlNYr|DbSJ5$y+!kmnE&GiwhO0jHJ^V6*rCxrSFDI}WX7`{7 zbz0lpw~fNfSgP7YHG??&T|?EK`ZrX)Tl}|N98Ocx)`qISGT#LuELTIr|E7j=zq=U} zYtLplQyB=#-Z09o(15$t zI9Tvcy-Ph5bUG7TO&x0|9^eyxzDu>nXVq(`-l(EoaoCl0f}k<4of-)T^ib0;DB~g7 zSt3LJw7$I>TGhitWb!Ka1GdO`O1NM34+PTzch0C7 zCar@ys_}dj1G#xacyqNhVu)1WJSj}tc(^l~~K>aN2GdSF5BC&aOz28IP`MlZ#v^~zo<462|# zz0`dTxVKE4sN|D|lLALr6ZryNL?IaO^cV=X?X712R~aw#RwearnzV7uuf;;{-fK|o zL>K{u+^6bCr?QyD!;4)s9q+f;Xs2=(&qh1flLZ?stj0J&>sW6PJ>2T0QLBY-X} z+45LZDZ}S56Vg9iR6twr!!kHYP3~7O*b{ajV8j#mt6^YHI`vVXsNyBOy}5JxsPOV@ zPW4mIL##V9P}Oc~^o4~fW-jh{WUiInwqdM1hcW}BpsmocS1Do;sNWa;R47n-rtBzn@(g&-C#%J`+V0BlG4Gf2wuA^9Quz=-V zeG`QaQ3Goy!&x0Re26D_umyv5pPNWALsU%^o-+hoP_p~WA=qI&Hh9_rb+LU&9nu-T zA%_wk0zXhfpFN~vZ5XqW$;=N>%Nell`2Aru6e{F?kEjp(rX2y@XWrP+Bf_sGyvxC& zxj#DB;k^|Thk20&Y@GHx$V@&Q;V@R>%b}-w76m=3>U8s5o9PGE>GtJ(cWYv8W_c>d zDsttzUwD*P!Nk=xu&1g|ONS~es5B1TdJ8Ll0<+|FX(;y5l{Dxv)u74-z0HA6qN7|H z6!RFys2i<&Ooc+=+5Z?i8(86EYF6mu&%|P#oGSpLRSQPCl+$2Nu~VEG*i7qFPU=@Zf_sz*@dcAbs6OwV-#OP^qk!gLQyy z2#bgp_A>V$_sBV~Clb*qlZE~-CMzt|uZ-0C^ z=v@}w_pEw2D0cr&wl7P<14Ebcta`0#nNcPWMLeB+UWL&s&#P*5_BpJx>CdZfx6YII zoO=1zDJcEYtx^`CuReG|^@u8%36k8x%KH?vfQ35!fstV0t(|j`0<9gzzNm)O{hJ4Z zk>tS1h9S`pIwQ__U7?~E)lgBJAz= z(o0y1(AvJN&Q>o1KFo-!gRwBK=`v---MW}<<(#w?Yo}};*KX@as)iodZt-9i z;45q-##Fn7``?v&cN7@p3+@x6)GN5hb2STd)c18YTb)nS?}e|cBIeQ#zoG6_8TQGh zN^h!1eE>zBDz+UP(?#G!nUwgZ8g{$X&D8EKwZlK1$5PWr-_D*R-MT; zT2%o_4j-)=t1NxEmmU}m_9}~(my0?yTD|ojSomk&Qv)%yYu^J?yNUL`r<#MrUw%)$ zZM6M8ALQ9%)uqKla2z)`YB5|Kb{nIH_9?ZAj8+oW1Ll^GB+^%KRL2AjLiUBk&zfnHL0K1FTm62yCW6?Qa3h z(y5PCBiIGvhJ?Bl9<7{kC&i{@FqLLqH+TcXm1AI4@;$*lqE#PbzRt@`lfLZWrrZbY z+&gGzw7OV5@#HO6q)J9S#L>56RU#elWcUs_cCP(4*c*{Gh6`4^+V(8~aGz@mR=* z>4EX!3J%lg@v1Q>SCk))Utu`_h-Zmx^>_%7GwJGh^o{4;#q#CFwi9;#0Yl50oyMVobu#pTz%Xs*$wKDJri|xgU>i)X+ z=~A4D(nmuhfS70;K;lU0?unTEW9hev>QUHH_K8-F z_CKQabnFx+elixb4=B~4EV>>KCSW@?oP=t2(|}2;PU9p6Z7$eoo+{~V)u>Ih02=2^ z)1Q<-oj-{ZCaHE+N`cI1unuxq(J}gZk_zvg&vAj)5By*ejYVf>p?>5DuMQmVu6V86 zfeSBAsLbFSa&v$_new>U;20_7;E#TW0`n0(WbbE@gw5{x~K1-DI@`>`c-W z^$_O&wcPXcJb?VT$RfNj?M7kQD@Cm6%o28 z0iDpS}) zR)a?BOU6ytW*n_y*$u(~mdGCWg&APm|F8JAS3gx_jEQvaQ#IhW?d&%Tc#Iz3)^v83 z>K~K@$PiE>ZX34J_fogns$W>Dh9PmD!{WrA2Hsdc5r`hbVsTI$}{UTi_H3+Qcpt*`qHN84l zJq-I$Rh0v zQ^2%NdkR3&$E3hSfprU16Oaz%?c~drp-;Ip#O2Fo&A&O@+|~Bam&yVP$0-D@#Yv zqC}MdUjg#6hi`*yBsJp%Yv0p3boz`k6_GlR#@$)72!%79~`BiE32i zPqx{M0KsCc15&<%TZ%zTz#11*^b+;91JcPKOH_ke%du@~3?6yFjErQ@@8H~9E(K?H zlqM`y&-ac?M>kfnir3-6yw!Am$>l%X04$&ke!uRGz=F{cGr5?ji5b*tnd*IS9DBg< zw=S&b2g+XNmjsUVs5|EJdn*57^3OH#`%Z5JmR{}#YP}4Q-qB^M!EJ{|EbM^r%s>N}5jR{>K3z1b``3`ewe`p^;935USl?BFYA zotK=-&v2MRIs>f~JE<-leW^feq8*Ar2+p)OiuOc)#?vwlxD)dt|_{KJy z@zm!4fQl}osFmu`m##5ztL@1>NIke(4eor#=q}7ld=S1jVKpb{OgEHBx?RHc&*{6B zs!6>V4RkS3SAlH= zpI3>AiD7Og@EyMfAXBIf+f*90N>kz0r~hO7EAt)8_=}!S1A)&(JZRpeG}Xb_LD^}l zR{gmXK=ZTFK5(6o(oJa0ydGj)8|jZU)jRY{M$f=H`MQ&5nC|FJ^xzuR7NjF?jk3G| zS!cgoo?!kA@OW%Rzgq**^RN?xeVA&kRby%={tV))F{0^3+3b=cfg>)`%C(SFCQ#8@ z)g<_Pg0K0y19T?YZR5M-81IM{8UEMVzWezV>&^;b(D~Ur+ zZ-^?SO|Os^$06nzb-6#;xU#A@RLG%f-cT-wf?ac{|9aJiDd5NJ(TW0Exn6az4=Bra z)ZjX(SD+TiU^u0tNp4VU`)U)7AT3Waz*B+&=e5MU6JQB#UaI-isvfWzn2kQE@Ty_3 zSGfqUQ@J=Q-JtHNSp>}k))#Zj_8aI^CJorALL518!nQ$msg+ae&Ek1OmeVDaxls+N znZ;=)7x%m&EdloU*T-sSplQV-QET(-mWvz|BI>Woe5!H~diGqS1DWcv zQ3c?K>=@4*%EaL^MSPQA;9!g@Rvpe({KFtoLw0Yp6{b3jP{K0PBU!@Fj~xMrjP^^R z_XTH^ZHFH?Qwv?wjLp!Rji*hURde=Lb7nJ8j$&%FMJ;vCWj^t&q%~QpFASU-Y*jr& z7Xoe2kT>W#t1aKmXD~1??NHr1*oXbB0v2;UpBT^F+Fbs_+Ay>t ziQh9>)Md^Ct;nL|JJf?bF0H>%7Aw1%L}T?V3<$)9s)l~or=Gs1DPJgp;eLZJRZOik zo1bmvhnnEf8r`iq+s$99EMQ~r?SvBQ0&Ur;I$^u$yGzxtpT%@qZx{Z&T^QE;n77)Y zn2GJ;j@{4(cyh+^a{Ny@7o$#

xvduT(AE&dGIj*#U4^^g#8{#2ID}>;PZ^*v8M~ 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

-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 BKmGs! delta 157714 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 H0l0~r5t61Oj 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 EAE Date: Thu, 1 Feb 2024 13:28:16 +0100 Subject: [PATCH 14/60] continue sql db implementation --- runtime/storage-locations/sql-db.ts | 39 ++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/runtime/storage-locations/sql-db.ts b/runtime/storage-locations/sql-db.ts index d39125c5..6222b9f4 100644 --- a/runtime/storage-locations/sql-db.ts +++ b/runtime/storage-locations/sql-db.ts @@ -9,6 +9,9 @@ import { Datex } from "../../mod.ts"; import { datex_type_mysql_map } from "./sql-type-map.ts"; import { NOT_EXISTING } from "../../runtime/constants.ts"; import { client_type } from "../../utils/constants.ts"; +import { Compiler } from "../../compiler/compiler.ts"; +import { ExecConditions } from "../../utils/global_types.ts"; +import { Runtime } from "../runtime.ts"; const logger = new Logger("SQL Storage"); @@ -36,6 +39,13 @@ export class SQLDBStorageLocation extends AsyncStorageLocation { [this.#pointerMysqlColumnName, this.#pointerMysqlType, "PRIMARY KEY"], ["table_name", "varchar(50)"] ] + }, + items: { + name: "datex_items", + columns: [ + ["key", "varchar(50)", "PRIMARY KEY"], + ["value", "blob"] + ] } } satisfies Record; @@ -48,6 +58,7 @@ export class SQLDBStorageLocation extends AsyncStorageLocation { async #connect(){ if (this.#connected) return; this.#sqlClient = await new Client().connect(this.#options); + this.log?.("Connected to SQL database " + this.#options.db + " on " + this.#options.hostname + ":" + this.#options.port) this.#connected = true; } @@ -196,7 +207,7 @@ export class SQLDBStorageLocation extends AsyncStorageLocation { async #setupMetaTables() { for (const definition of Object.values(this.#metaTables)) { const createdNew = await this.#createTableIfNotExists(definition); - if (createdNew) logger.debug("Created meta table '" + definition.name + "'") + if (createdNew) this.log?.("Created meta table '" + definition.name + "'") } } @@ -274,10 +285,24 @@ export class SQLDBStorageLocation extends AsyncStorageLocation { } async setItem(key: string,value: unknown) { - + await this.#init(); + const dependencies = new Set() + const encoded = Compiler.encodeValue(value, dependencies); + await this.#query('INSERT INTO ?? ?? VALUES ?;', [this.#metaTables.items.name, ["key", "value"], [key, encoded]]) + // await datex_item_storage.setItem(key, Compiler.encodeValue(value, dependencies)); + return dependencies; } - async getItem(key: string): Promise { - + async getItem(key: string, conditions: ExecConditions): Promise { + const encoded = (await this.#queryFirst<{value: ArrayBuffer}>( + new Query() + .table(this.#metaTables.items.name) + .select("value") + .where(Where.eq("key", key)) + .build() + )); + console.log("encoded",encoded) + if (!encoded) return null; + else return Runtime.decodeValue(encoded, false, conditions); } async hasItem(key:string) { @@ -303,8 +328,10 @@ export class SQLDBStorageLocation extends AsyncStorageLocation { } async setPointer(pointer: Pointer, partialUpdateKey: unknown|typeof NOT_EXISTING): Promise>> { + const dependencies = new Set() + await this.#init(); - this.log("update " + pointer.id + " - " + pointer.type, partialUpdateKey, await this.#pointerEntryExists(pointer)) + this.log?.("update " + pointer.id + " - " + pointer.type, partialUpdateKey, await this.#pointerEntryExists(pointer)) // new full insert if (!await this.#pointerEntryExists(pointer)) @@ -322,7 +349,7 @@ export class SQLDBStorageLocation extends AsyncStorageLocation { } - return new Set(); + return dependencies; } async getPointerValue(pointerId: string, outer_serialized: boolean): Promise { From 637da6a1c61e01a94befac341e039bd00d71991e Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 1 Feb 2024 17:28:58 +0100 Subject: [PATCH 15/60] fix decompiler, add panic hook (unrelated) --- utils/message_logger.ts | 2 +- wasm/adapter/Cargo.lock | 1 + wasm/adapter/Cargo.toml | 3 ++- wasm/adapter/pkg/datex_wasm.d.ts | 4 ++++ wasm/adapter/pkg/datex_wasm.js | 26 ++++++++++++++++++++++- wasm/adapter/pkg/datex_wasm_bg.wasm | Bin 806073 -> 809212 bytes wasm/adapter/pkg/datex_wasm_bg.wasm.d.ts | 1 + wasm/adapter/src/lib.rs | 11 ++++++++++ 8 files changed, 45 insertions(+), 3 deletions(-) diff --git a/utils/message_logger.ts b/utils/message_logger.ts index 45518c6c..60f2f7fc 100644 --- a/utils/message_logger.ts +++ b/utils/message_logger.ts @@ -24,7 +24,7 @@ export class MessageLogger { return wasm_decompile(new Uint8Array(dxb), true, colorized, resolve_slots).replace(/\r\n$/, ''); } catch (e) { - return "Decompiler Error: "+ e.message; + return "Decompiler Error: " + e.message; } } diff --git a/wasm/adapter/Cargo.lock b/wasm/adapter/Cargo.lock index 5d676380..c9927f04 100644 --- a/wasm/adapter/Cargo.lock +++ b/wasm/adapter/Cargo.lock @@ -199,6 +199,7 @@ dependencies = [ name = "datex-wasm" version = "0.1.0" dependencies = [ + "console_error_panic_hook", "datex-core", "datex_cli_core", "lazy_static", diff --git a/wasm/adapter/Cargo.toml b/wasm/adapter/Cargo.toml index 167ad45a..7c4efb7f 100644 --- a/wasm/adapter/Cargo.toml +++ b/wasm/adapter/Cargo.toml @@ -12,6 +12,7 @@ wasm-bindgen = "0.2.63" datex-core = { path = "../../../datex-core" } datex_cli_core = { path = "../../../datex_cli_core" } lazy_static = "1.4.0" +console_error_panic_hook = "0.1.7" [dependencies.web-sys] version = "0.3.60" @@ -24,7 +25,7 @@ lazy_static = "1.4.0" # logging them with `console.error`. This is great for development, but requires # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for # code size when deploying. -console_error_panic_hook = { version = "0.1.6", optional = true } +console_error_panic_hook = { version = "0.1.7" } # `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size # compared to the default allocator's ~10K. It is slower than the default diff --git a/wasm/adapter/pkg/datex_wasm.d.ts b/wasm/adapter/pkg/datex_wasm.d.ts index ed03d247..293ef981 100644 --- a/wasm/adapter/pkg/datex_wasm.d.ts +++ b/wasm/adapter/pkg/datex_wasm.d.ts @@ -2,6 +2,9 @@ /* eslint-disable */ /** */ +export function init_panic_hook(): void; +/** +*/ export function init_runtime(): void; /** * @param {string} datex_script @@ -23,6 +26,7 @@ export interface InitOutput { readonly memory: WebAssembly.Memory; readonly compile: (a: number, b: number, c: number) => void; readonly decompile: (a: number, b: number, c: number, d: number, e: number, f: number) => void; + readonly init_panic_hook: () => void; readonly init_runtime: () => void; readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_malloc: (a: number) => number; diff --git a/wasm/adapter/pkg/datex_wasm.js b/wasm/adapter/pkg/datex_wasm.js index 3ceeba84..53922577 100644 --- a/wasm/adapter/pkg/datex_wasm.js +++ b/wasm/adapter/pkg/datex_wasm.js @@ -46,10 +46,16 @@ function takeObject(idx) { dropObject(idx); return ret; } +/** +*/ +export function init_panic_hook() { + wasm.init_panic_hook(); +} + /** */ export function init_runtime() { - wasm.init_runtime(); + wasm.init_panic_hook(); } let WASM_VECTOR_LEN = 0; @@ -203,6 +209,24 @@ function getImports() { imports.wbg.__wbindgen_object_drop_ref = function(arg0) { takeObject(arg0); }; + imports.wbg.__wbg_new_abda76e883ba8a5f = function() { + const ret = new Error(); + return addHeapObject(ret); + }; + imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { + const ret = getObject(arg1).stack; + const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { + try { + console.error(getStringFromWasm0(arg0, arg1)); + } finally { + wasm.__wbindgen_free(arg0, arg1); + } + }; imports.wbg.__wbg_log_4b5638ad60bdc54a = function(arg0) { console.log(getObject(arg0)); }; diff --git a/wasm/adapter/pkg/datex_wasm_bg.wasm b/wasm/adapter/pkg/datex_wasm_bg.wasm index 5413551fe8adb9863f9f87e026358d62eb5028de..0492d86cee9c3a7b83eed65e5f1d8e16450c155d 100644 GIT binary patch delta 177338 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

c6)V<3#Cl?9&(>#D1BTqP;u+AG#R}VX(m-b{h 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 Date: Thu, 1 Feb 2024 17:37:45 +0100 Subject: [PATCH 16/60] disable panic hooks --- wasm/adapter/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wasm/adapter/src/lib.rs b/wasm/adapter/src/lib.rs index 188cd3e4..31abc990 100644 --- a/wasm/adapter/src/lib.rs +++ b/wasm/adapter/src/lib.rs @@ -23,13 +23,13 @@ use web_sys::console; use std::panic; -use console_error_panic_hook::set_once as set_panic_hook; +// use console_error_panic_hook::set_once as set_panic_hook; -#[wasm_bindgen] -pub fn init_panic_hook() { - set_panic_hook(); -} +// #[wasm_bindgen] +// pub fn init_panic_hook() { +// set_panic_hook(); +// } // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global @@ -68,7 +68,7 @@ extern "C" { pub fn init_runtime() { // let logger = Logger::new_for_development(&LOGGER, "DATEX"); // logger.success("initialized"); - init_panic_hook(); + // init_panic_hook(); return } From 7f61c798cae4131d038d055d38dba29d0844dbe8 Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 1 Feb 2024 17:38:04 +0100 Subject: [PATCH 17/60] disable panic hooks --- wasm/adapter/pkg/datex_wasm.d.ts | 4 ---- wasm/adapter/pkg/datex_wasm.js | 26 +---------------------- wasm/adapter/pkg/datex_wasm_bg.wasm | Bin 809212 -> 805968 bytes wasm/adapter/pkg/datex_wasm_bg.wasm.d.ts | 1 - 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/wasm/adapter/pkg/datex_wasm.d.ts b/wasm/adapter/pkg/datex_wasm.d.ts index 293ef981..ed03d247 100644 --- a/wasm/adapter/pkg/datex_wasm.d.ts +++ b/wasm/adapter/pkg/datex_wasm.d.ts @@ -2,9 +2,6 @@ /* eslint-disable */ /** */ -export function init_panic_hook(): void; -/** -*/ export function init_runtime(): void; /** * @param {string} datex_script @@ -26,7 +23,6 @@ export interface InitOutput { readonly memory: WebAssembly.Memory; readonly compile: (a: number, b: number, c: number) => void; readonly decompile: (a: number, b: number, c: number, d: number, e: number, f: number) => void; - readonly init_panic_hook: () => void; readonly init_runtime: () => void; readonly __wbindgen_add_to_stack_pointer: (a: number) => number; readonly __wbindgen_malloc: (a: number) => number; diff --git a/wasm/adapter/pkg/datex_wasm.js b/wasm/adapter/pkg/datex_wasm.js index 53922577..3ceeba84 100644 --- a/wasm/adapter/pkg/datex_wasm.js +++ b/wasm/adapter/pkg/datex_wasm.js @@ -46,16 +46,10 @@ function takeObject(idx) { dropObject(idx); return ret; } -/** -*/ -export function init_panic_hook() { - wasm.init_panic_hook(); -} - /** */ export function init_runtime() { - wasm.init_panic_hook(); + wasm.init_runtime(); } let WASM_VECTOR_LEN = 0; @@ -209,24 +203,6 @@ function getImports() { imports.wbg.__wbindgen_object_drop_ref = function(arg0) { takeObject(arg0); }; - imports.wbg.__wbg_new_abda76e883ba8a5f = function() { - const ret = new Error(); - return addHeapObject(ret); - }; - imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { - const ret = getObject(arg1).stack; - const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len0; - getInt32Memory0()[arg0 / 4 + 0] = ptr0; - }; - imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { - try { - console.error(getStringFromWasm0(arg0, arg1)); - } finally { - wasm.__wbindgen_free(arg0, arg1); - } - }; imports.wbg.__wbg_log_4b5638ad60bdc54a = function(arg0) { console.log(getObject(arg0)); }; diff --git a/wasm/adapter/pkg/datex_wasm_bg.wasm b/wasm/adapter/pkg/datex_wasm_bg.wasm index 0492d86cee9c3a7b83eed65e5f1d8e16450c155d..c6f42979a20e8e27cb11cdf7c52fe71873a03e57 100644 GIT binary patch delta 170678 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 YITtQmQg(>lk%y)?ycRugcKEvg3shnjPXGV_ delta 173738 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

DeVM-p2QZ%lJDAUdgP4B+ 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 Uzief(|KxI3T}SA}dEPbu7f#u(AOHXW diff --git a/wasm/adapter/pkg/datex_wasm_bg.wasm.d.ts b/wasm/adapter/pkg/datex_wasm_bg.wasm.d.ts index f2615703..e190e46c 100644 --- a/wasm/adapter/pkg/datex_wasm_bg.wasm.d.ts +++ b/wasm/adapter/pkg/datex_wasm_bg.wasm.d.ts @@ -3,7 +3,6 @@ export const memory: WebAssembly.Memory; export function compile(a: number, b: number, c: number): void; export function decompile(a: number, b: number, c: number, d: number, e: number, f: number): void; -export function init_panic_hook(): void; export function init_runtime(): void; export function __wbindgen_add_to_stack_pointer(a: number): number; export function __wbindgen_malloc(a: number): number; From 5a95a1b9b41e6ded4711df88e5deadadd7c6e467 Mon Sep 17 00:00:00 2001 From: benStre Date: Thu, 1 Feb 2024 17:51:44 +0100 Subject: [PATCH 18/60] fix storage snapshio formatting --- runtime/storage.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/runtime/storage.ts b/runtime/storage.ts index 971878ea..50c6a034 100644 --- a/runtime/storage.ts +++ b/runtime/storage.ts @@ -16,6 +16,7 @@ import { ESCAPE_SEQUENCES } from "../utils/logger.ts"; import { StorageMap } from "../types/storage_map.ts"; import { StorageSet } from "../types/storage_set.ts"; import { IterableWeakSet } from "../utils/iterable-weak-set.ts"; +import { LazyPointer } from "./lazy-pointer.ts"; // displayInit(); @@ -1172,10 +1173,6 @@ export class Storage { else throw new Error("Cannot find or create the state '" + id + "'") } - static #replaceLastOccurenceOf(search: string, replace: string, str: string) { - const n = str.lastIndexOf(search); - return str.substring(0, n) + replace + str.substring(n + search.length); - } public static async printSnapshot(options: StorageSnapshotOptions = {internalItems: false, expandStorageMapsAndSets: true}) { const {items, pointers} = await this.getSnapshot(options); @@ -1205,7 +1202,7 @@ export class Storage { const storedInAll = [...this.#locations.keys()].every(l => locations.includes(l)); const value = [...storageMap.values()][0]; - string += ` • ${COLOR_PTR}$${key}${ESCAPE_SEQUENCES.GREY}${storedInAll ? "" : (` (only in ${locations.map(l=>l.name).join(",")})`)} = ${this.#replaceLastOccurenceOf("\n ", "", value.replaceAll("\n", "\n "))}\n` + string += ` • ${COLOR_PTR}$${key}${ESCAPE_SEQUENCES.GREY}${storedInAll ? "" : (` (only in ${locations.map(l=>l.name).join(",")})`)} = ${value.replaceAll("\n", "\n ")}\n` } console.log(string+"\n"); @@ -1219,7 +1216,7 @@ export class Storage { const storedInAll = [...this.#locations.keys()].every(l => locations.includes(l)); const value = [...storageMap.values()][0]; - string += ` • ${key}${ESCAPE_SEQUENCES.GREY}${storedInAll ? "" : (` (only in ${locations.map(l=>l.name).join(",")})`)} = ${value}` + string += ` • ${key}${ESCAPE_SEQUENCES.GREY}${storedInAll ? "" : (` (only in ${locations.map(l=>l.name).join(",")})`)} = ${value}\n` } console.log(string+"\n"); @@ -1275,7 +1272,7 @@ export class Storage { string += `${ESCAPE_SEQUENCES.ITALIC}Inconsistencies between storage locations don't necessarily indicate that something is wrong. They can occur when a storage location is not updated immediately (e.g. when only using SAVE_ON_EXIT).\n\n${ESCAPE_SEQUENCES.RESET}` for (const [key, storageMap] of pointers.inconsistencies) { for (const [location, value] of storageMap) { - string += ` • ${COLOR_PTR}$${key}${ESCAPE_SEQUENCES.GREY} (${(location.name+")").padEnd(15, " ")} = ${this.#replaceLastOccurenceOf("\n ", "", value.replaceAll("\n", "\n "))}\n` + string += ` • ${COLOR_PTR}$${key}${ESCAPE_SEQUENCES.GREY} (${(location.name+")").padEnd(15, " ")} = ${value.replaceAll("\n", "\n ")}\n` } string += `\n` } @@ -1309,13 +1306,18 @@ export class Storage { if (value.startsWith("\x1b[38;2;50;153;220m") || value.startsWith("\x1b[38;2;50;153;220m")) { const ptr = await Pointer.load(ptrId, undefined, true); + if (ptr instanceof LazyPointer) { + console.error("LazyPointer in StorageMap/StorageSet"); + continue; + } if (ptr.val instanceof StorageMap) { const map = ptr.val; let inner = ""; for await (const [key, val] of map) { inner += ` ${Runtime.valueToDatexStringExperimental(key, true, true)}\x1b[0m => ${Runtime.valueToDatexStringExperimental(val, true, true)}\n` } - if (inner) storageMap.set(location, "\x1b[38;2;50;153;220m \x1b[0m{\n"+inner+"\x1b[0m\n}") + // substring: remove last \n + if (inner) storageMap.set(location, "\x1b[38;2;50;153;220m \x1b[0m{\n"+inner.substring(0, inner.length-1)+"\x1b[0m\n}") } else if (ptr.val instanceof StorageSet) { const set = ptr.val; @@ -1323,7 +1325,8 @@ export class Storage { for await (const val of set) { inner += ` ${Runtime.valueToDatexStringExperimental(val, true, true)},\n` } - if (inner) storageMap.set(location, "\x1b[38;2;50;153;220m \x1b[0m{\n"+inner+"\x1b[0m\n}") + // substring: remove last \n + if (inner) storageMap.set(location, "\x1b[38;2;50;153;220m \x1b[0m{\n"+inner.substring(0, inner.length-1)+"\x1b[0m\n}") } } } From f768352df3fc1057268691ca94b183240ca4ef3e Mon Sep 17 00:00:00 2001 From: benStre Date: Fri, 2 Feb 2024 15:48:31 +0100 Subject: [PATCH 19/60] rename storage-map/storage-set.ts --- types/storage-map.ts | 218 +++++++++++++++++++++++++++++++++++++++ types/storage-set.ts | 233 ++++++++++++++++++++++++++++++++++++++++++ types/storage_map.ts | 220 +--------------------------------------- types/storage_set.ts | 235 +------------------------------------------ 4 files changed, 455 insertions(+), 451 deletions(-) create mode 100644 types/storage-map.ts create mode 100644 types/storage-set.ts diff --git a/types/storage-map.ts b/types/storage-map.ts new file mode 100644 index 00000000..65bd9b22 --- /dev/null +++ b/types/storage-map.ts @@ -0,0 +1,218 @@ +// deno-lint-ignore-file no-this-alias + +import { Compiler } from "../compiler/compiler.ts"; +import { DX_PTR } from "../runtime/constants.ts"; +import { Pointer } from "../runtime/pointers.ts"; +import { Storage } from "../runtime/storage.ts"; +import { Logger } from "../utils/logger.ts"; + +const logger = new Logger("StorageMap"); + + +/** + * WeakMap that outsources values to storage. + * The API is similar to the JS WeakMap API, but all methods are async. + * In contrast to JS WeakMaps, primitive keys are also allowed. + * The StorageWeakMap holds no strong references to its keys in storage. + * This means that the pointer of a key can be garbage collected. + */ +export class StorageWeakMap { + + #prefix?: string; + + constructor(){ + Pointer.proxifyValue(this) + } + + + static async from(entries: readonly (readonly [K, V])[]){ + const map = $$(new StorageWeakMap()); + for (const [key, value] of entries) await map.set(key, value); + return map; + } + + protected get _prefix() { + if (!this.#prefix) this.#prefix = 'dxmap::'+(this as any)[DX_PTR].idString()+'.'; + return this.#prefix; + } + + async get(key: K): Promise { + const storage_key = await this.getStorageKey(key); + return this._get(storage_key); + } + protected _get(storage_key:string) { + this.activateCacheTimeout(storage_key); + return Storage.getItem(storage_key); + } + + async has(key: K): Promise { + const storage_key = await this.getStorageKey(key); + return this._has(storage_key); + } + protected _has(storage_key:string) { + return Storage.hasItem(storage_key) + } + + async delete(key: K) { + const storage_key = await this.getStorageKey(key); + return this._delete(storage_key); + } + protected _delete(storage_key:string) { + return Storage.removeItem(storage_key) + } + + + async set(key: K, value:V) { + const storage_key = await this.getStorageKey(key); + return this._set(storage_key, value); + } + protected _set(storage_key:string, value:V) { + this.activateCacheTimeout(storage_key); + return Storage.setItem(storage_key, value) + } + + protected activateCacheTimeout(storage_key:string){ + setTimeout(()=>{ + logger.debug("removing item from cache: " + storage_key); + Storage.cache.delete(storage_key) + }, 60_000); + } + + protected async getStorageKey(key: K) { + const keyHash = await Compiler.getUniqueValueIdentifier(key); + // @ts-ignore DX_PTR + return this._prefix + keyHash; + } + + async clear() { + const promises = []; + for (const key of await Storage.getItemKeysStartingWith(this._prefix)) { + promises.push(Storage.removeItem(key)); + } + await Promise.all(promises); + } + +} + +/** + * Set that outsources values to storage. + * The API is similar to the JS Map API, but all methods are async. + */ +export class StorageMap extends StorageWeakMap { + + static override async from(entries: readonly (readonly [K, V])[]){ + const map = $$(new StorageMap()); + for (const [key, value] of entries) await map.set(key, value); + return map; + } + + #key_prefix = 'key.' + + override async set(key: K, value: V): Promise { + const storage_key = await this.getStorageKey(key); + const storage_item_key = this.#key_prefix + storage_key; + // store value + await this._set(storage_key, value); + // store key + this.activateCacheTimeout(storage_item_key); + return Storage.setItem(storage_item_key, key) + } + + override async delete(key: K) { + const storage_key = await this.getStorageKey(key); + const storage_item_key = this.#key_prefix + storage_key; + // delete value + await this._delete(storage_key); + // delete key + return Storage.removeItem(storage_item_key) + } + + /** + * Async iterator that returns all keys. + */ + keys() { + const self = this; + const key_prefix = this.#key_prefix; + return (async function*(){ + const keyGenerator = await Storage.getItemKeysStartingWith(self._prefix); + + for (const key of keyGenerator) { + const keyValue = await Storage.getItem(key_prefix+key); + yield ( keyValue); + } + })() + } + + /** + * Returns an array containing all keys. + * This can be used to iterate over the keys without using a (for await of) loop. + */ + async keysArray() { + const keys = []; + for await (const key of this.keys()) keys.push(key); + return keys; + } + + /** + * Async iterator that returns all values. + */ + values() { + const self = this; + return (async function*(){ + const keyGenerator = await Storage.getItemKeysStartingWith(self._prefix); + + for (const key of keyGenerator) { + const value = await Storage.getItem(key); + yield ( value); + } + })() + } + + /** + * Returns an array containing all values. + * This can be used to iterate over the values without using a (for await of) loop. + */ + async valuesArray() { + const values = []; + for await (const value of this.values()) values.push(value); + return values; + } + + /** + * Async iterator that returns all entries. + */ + entries() { + return this[Symbol.asyncIterator]() + } + + /** + * Returns an array containing all entries. + * This can be used to iterate over the entries without using a (for await of) loop. + */ + async entriesArray() { + const entries = []; + for await (const entry of this.entries()) entries.push(entry); + return entries; + } + + async *[Symbol.asyncIterator]() { + const keyGenerator = await Storage.getItemKeysStartingWith(this._prefix); + + for (const key of keyGenerator) { + const keyValue = await Storage.getItem(this.#key_prefix+key); + const value = await Storage.getItem(key); + yield (<[K,V]> [keyValue, value]); + } + } + + override async clear() { + const promises = []; + for (const key of await Storage.getItemKeysStartingWith(this._prefix)) { + promises.push(await Storage.removeItem(key)); + promises.push(await Storage.removeItem(this.#key_prefix+key)); + } + await Promise.all(promises); + } + + +} \ No newline at end of file diff --git a/types/storage-set.ts b/types/storage-set.ts new file mode 100644 index 00000000..95635256 --- /dev/null +++ b/types/storage-set.ts @@ -0,0 +1,233 @@ +// deno-lint-ignore-file no-this-alias + +import { Compiler } from "../compiler/compiler.ts"; +import { DX_PTR } from "../runtime/constants.ts"; +import { Pointer } from "../runtime/pointers.ts"; +import { Storage } from "../runtime/storage.ts"; +import { Logger } from "../utils/logger.ts"; + +const logger = new Logger("StorageSet"); + +/** + * WeakSet that outsources values to storage. + * The API is similar to the JS WeakSet API, but all methods are async. + * In contrast to JS WeakSets, primitive values are also allowed. + * The StorageWeakSet holds no strong references to its values in storage. + * This means that the pointer of a value can be garbage collected. + */ +export class StorageWeakSet { + + #prefix?: string; + + constructor(){ + Pointer.proxifyValue(this) + } + + static async from(values: readonly V[]) { + const set = $$(new StorageSet()); + for (const v of values) await set.add(v); + return set; + } + + protected get _prefix() { + if (!this.#prefix) this.#prefix = 'dxset::'+(this as any)[DX_PTR].idString()+'.'; + return this.#prefix; + } + + async add(value: V) { + const storage_key = await this.getStorageKey(value); + if (await this._has(storage_key)) return this; // already exists + await this._add(storage_key, null); + return this; + } + protected _add(storage_key:string, value:V|null) { + this.activateCacheTimeout(storage_key); + return Storage.setItem(storage_key, value); + } + + async has(value: V): Promise { + const storage_key = await this.getStorageKey(value); + return this._has(storage_key); + } + protected _has(storage_key:string) { + return Storage.hasItem(storage_key) + } + + async delete(value: V) { + const storage_key = await this.getStorageKey(value); + return this._delete(storage_key); + } + protected _delete(storage_key:string) { + return Storage.removeItem(storage_key) + } + + protected activateCacheTimeout(storage_key:string){ + setTimeout(()=>{ + logger.debug("removing item from cache: " + storage_key); + Storage.cache.delete(storage_key) + }, 60_000); + } + + protected async getStorageKey(value: V) { + const keyHash = await Compiler.getUniqueValueIdentifier(value); + // @ts-ignore DX_PTR + return this._prefix + keyHash; + } + + async clear() { + const promises = []; + for (const key of await Storage.getItemKeysStartingWith(this._prefix)) { + promises.push(await Storage.removeItem(key)); + } + await Promise.all(promises); + } + + +} + +/** + * Set that outsources values to storage. + * The API is similar to the JS Set API, but all methods are async. + */ +export class StorageSet extends StorageWeakSet { + + #size_key?: string + protected get _size_key() { + if (!this.#size_key) this.#size_key = 'dxset.size::'+(this as any)[DX_PTR].idString()+'.'; + return this.#size_key; + } + + #size?: number; + + get size() { + if (this.#size == undefined) throw new Error("size not yet available. use getSize() instead"); + return this.#size; + } + + async getSize() { + if (this.#size != undefined) return this.#size; + else { + await this.#determineSizeFromStorage(); + return this.#size! + } + } + + /** + * Sets this.#size to the correct value determined from storage. + */ + async #determineSizeFromStorage() { + const cachedSize = await Storage.getItem(this._size_key); + const calculatedSize = await Storage.getItemCountStartingWith(this._prefix); + if (cachedSize !== calculatedSize) { + if (cachedSize != undefined) + logger.warn(`Size mismatch for StorageSet (${(this as any)[DX_PTR].idString()}) detected. Setting size to ${calculatedSize}`) + await this.#updateSize(calculatedSize); + } + else this.#size = calculatedSize; + } + + async #updateSize(newSize: number) { + this.#size = newSize; + await Storage.setItem(this._size_key, newSize); + } + + async #incrementSize() { + await this.#updateSize(await this.getSize() + 1); + } + + async #decrementSize() { + await this.#updateSize(await this.getSize() - 1); + } + + + /** + * Appends a new value to the StorageWeakSet. + */ + async add(value: V) { + const storage_key = await this.getStorageKey(value); + if (await this._has(storage_key)) return this; // already exists + await this._add(storage_key, value); + await this.#incrementSize(); + return this; + } + + async delete(value: V) { + const wasDeleted = await super.delete(value); + if (wasDeleted) await this.#decrementSize(); + return wasDeleted; + } + + async clear(): Promise { + await super.clear(); + await this.#updateSize(0); + } + + /** + * Async iterator that returns all keys. + */ + keys() { + return this[Symbol.asyncIterator]() + } + + /** + * Returns an array containing all keys. + * This can be used to iterate over the keys without using a (for await of) loop. + */ + async keysArray() { + const keys = []; + for await (const key of this.keys()) keys.push(key); + return keys; + } + + /** + * Async iterator that returns all values. + */ + values() { + return this[Symbol.asyncIterator]() + } + + /** + * Returns an array containing all values. + * This can be used to iterate over the values without using a (for await of) loop. + */ + async valuesArray() { + const values = []; + for await (const value of this.values()) values.push(value); + return values; + } + + /** + * Async iterator that returns all entries. + */ + entries() { + const self = this; + return (async function*(){ + const keyGenerator = await Storage.getItemKeysStartingWith(self._prefix); + + for (const key of keyGenerator) { + const value = await Storage.getItem(key); + yield (<[V,V]> [value,value]); + } + })() + } + + /** + * Returns an array containing all entries. + * This can be used to iterate over the entries without using a (for await of) loop. + */ + async entriesArray() { + const entries = []; + for await (const entry of this.entries()) entries.push(entry); + return entries; + } + + async *[Symbol.asyncIterator]() { + const keyGenerator = await Storage.getItemKeysStartingWith(this._prefix); + + for (const key of keyGenerator) { + const value = await Storage.getItem(key); + yield ( value); + } + } + +} \ No newline at end of file diff --git a/types/storage_map.ts b/types/storage_map.ts index 65bd9b22..55d8e655 100644 --- a/types/storage_map.ts +++ b/types/storage_map.ts @@ -1,218 +1,2 @@ -// deno-lint-ignore-file no-this-alias - -import { Compiler } from "../compiler/compiler.ts"; -import { DX_PTR } from "../runtime/constants.ts"; -import { Pointer } from "../runtime/pointers.ts"; -import { Storage } from "../runtime/storage.ts"; -import { Logger } from "../utils/logger.ts"; - -const logger = new Logger("StorageMap"); - - -/** - * WeakMap that outsources values to storage. - * The API is similar to the JS WeakMap API, but all methods are async. - * In contrast to JS WeakMaps, primitive keys are also allowed. - * The StorageWeakMap holds no strong references to its keys in storage. - * This means that the pointer of a key can be garbage collected. - */ -export class StorageWeakMap { - - #prefix?: string; - - constructor(){ - Pointer.proxifyValue(this) - } - - - static async from(entries: readonly (readonly [K, V])[]){ - const map = $$(new StorageWeakMap()); - for (const [key, value] of entries) await map.set(key, value); - return map; - } - - protected get _prefix() { - if (!this.#prefix) this.#prefix = 'dxmap::'+(this as any)[DX_PTR].idString()+'.'; - return this.#prefix; - } - - async get(key: K): Promise { - const storage_key = await this.getStorageKey(key); - return this._get(storage_key); - } - protected _get(storage_key:string) { - this.activateCacheTimeout(storage_key); - return Storage.getItem(storage_key); - } - - async has(key: K): Promise { - const storage_key = await this.getStorageKey(key); - return this._has(storage_key); - } - protected _has(storage_key:string) { - return Storage.hasItem(storage_key) - } - - async delete(key: K) { - const storage_key = await this.getStorageKey(key); - return this._delete(storage_key); - } - protected _delete(storage_key:string) { - return Storage.removeItem(storage_key) - } - - - async set(key: K, value:V) { - const storage_key = await this.getStorageKey(key); - return this._set(storage_key, value); - } - protected _set(storage_key:string, value:V) { - this.activateCacheTimeout(storage_key); - return Storage.setItem(storage_key, value) - } - - protected activateCacheTimeout(storage_key:string){ - setTimeout(()=>{ - logger.debug("removing item from cache: " + storage_key); - Storage.cache.delete(storage_key) - }, 60_000); - } - - protected async getStorageKey(key: K) { - const keyHash = await Compiler.getUniqueValueIdentifier(key); - // @ts-ignore DX_PTR - return this._prefix + keyHash; - } - - async clear() { - const promises = []; - for (const key of await Storage.getItemKeysStartingWith(this._prefix)) { - promises.push(Storage.removeItem(key)); - } - await Promise.all(promises); - } - -} - -/** - * Set that outsources values to storage. - * The API is similar to the JS Map API, but all methods are async. - */ -export class StorageMap extends StorageWeakMap { - - static override async from(entries: readonly (readonly [K, V])[]){ - const map = $$(new StorageMap()); - for (const [key, value] of entries) await map.set(key, value); - return map; - } - - #key_prefix = 'key.' - - override async set(key: K, value: V): Promise { - const storage_key = await this.getStorageKey(key); - const storage_item_key = this.#key_prefix + storage_key; - // store value - await this._set(storage_key, value); - // store key - this.activateCacheTimeout(storage_item_key); - return Storage.setItem(storage_item_key, key) - } - - override async delete(key: K) { - const storage_key = await this.getStorageKey(key); - const storage_item_key = this.#key_prefix + storage_key; - // delete value - await this._delete(storage_key); - // delete key - return Storage.removeItem(storage_item_key) - } - - /** - * Async iterator that returns all keys. - */ - keys() { - const self = this; - const key_prefix = this.#key_prefix; - return (async function*(){ - const keyGenerator = await Storage.getItemKeysStartingWith(self._prefix); - - for (const key of keyGenerator) { - const keyValue = await Storage.getItem(key_prefix+key); - yield ( keyValue); - } - })() - } - - /** - * Returns an array containing all keys. - * This can be used to iterate over the keys without using a (for await of) loop. - */ - async keysArray() { - const keys = []; - for await (const key of this.keys()) keys.push(key); - return keys; - } - - /** - * Async iterator that returns all values. - */ - values() { - const self = this; - return (async function*(){ - const keyGenerator = await Storage.getItemKeysStartingWith(self._prefix); - - for (const key of keyGenerator) { - const value = await Storage.getItem(key); - yield ( value); - } - })() - } - - /** - * Returns an array containing all values. - * This can be used to iterate over the values without using a (for await of) loop. - */ - async valuesArray() { - const values = []; - for await (const value of this.values()) values.push(value); - return values; - } - - /** - * Async iterator that returns all entries. - */ - entries() { - return this[Symbol.asyncIterator]() - } - - /** - * Returns an array containing all entries. - * This can be used to iterate over the entries without using a (for await of) loop. - */ - async entriesArray() { - const entries = []; - for await (const entry of this.entries()) entries.push(entry); - return entries; - } - - async *[Symbol.asyncIterator]() { - const keyGenerator = await Storage.getItemKeysStartingWith(this._prefix); - - for (const key of keyGenerator) { - const keyValue = await Storage.getItem(this.#key_prefix+key); - const value = await Storage.getItem(key); - yield (<[K,V]> [keyValue, value]); - } - } - - override async clear() { - const promises = []; - for (const key of await Storage.getItemKeysStartingWith(this._prefix)) { - promises.push(await Storage.removeItem(key)); - promises.push(await Storage.removeItem(this.#key_prefix+key)); - } - await Promise.all(promises); - } - - -} \ No newline at end of file +// TODO: deprecated module path, remove +export * from "./storage-map.ts"; \ No newline at end of file diff --git a/types/storage_set.ts b/types/storage_set.ts index 95635256..d015b40e 100644 --- a/types/storage_set.ts +++ b/types/storage_set.ts @@ -1,233 +1,2 @@ -// deno-lint-ignore-file no-this-alias - -import { Compiler } from "../compiler/compiler.ts"; -import { DX_PTR } from "../runtime/constants.ts"; -import { Pointer } from "../runtime/pointers.ts"; -import { Storage } from "../runtime/storage.ts"; -import { Logger } from "../utils/logger.ts"; - -const logger = new Logger("StorageSet"); - -/** - * WeakSet that outsources values to storage. - * The API is similar to the JS WeakSet API, but all methods are async. - * In contrast to JS WeakSets, primitive values are also allowed. - * The StorageWeakSet holds no strong references to its values in storage. - * This means that the pointer of a value can be garbage collected. - */ -export class StorageWeakSet { - - #prefix?: string; - - constructor(){ - Pointer.proxifyValue(this) - } - - static async from(values: readonly V[]) { - const set = $$(new StorageSet()); - for (const v of values) await set.add(v); - return set; - } - - protected get _prefix() { - if (!this.#prefix) this.#prefix = 'dxset::'+(this as any)[DX_PTR].idString()+'.'; - return this.#prefix; - } - - async add(value: V) { - const storage_key = await this.getStorageKey(value); - if (await this._has(storage_key)) return this; // already exists - await this._add(storage_key, null); - return this; - } - protected _add(storage_key:string, value:V|null) { - this.activateCacheTimeout(storage_key); - return Storage.setItem(storage_key, value); - } - - async has(value: V): Promise { - const storage_key = await this.getStorageKey(value); - return this._has(storage_key); - } - protected _has(storage_key:string) { - return Storage.hasItem(storage_key) - } - - async delete(value: V) { - const storage_key = await this.getStorageKey(value); - return this._delete(storage_key); - } - protected _delete(storage_key:string) { - return Storage.removeItem(storage_key) - } - - protected activateCacheTimeout(storage_key:string){ - setTimeout(()=>{ - logger.debug("removing item from cache: " + storage_key); - Storage.cache.delete(storage_key) - }, 60_000); - } - - protected async getStorageKey(value: V) { - const keyHash = await Compiler.getUniqueValueIdentifier(value); - // @ts-ignore DX_PTR - return this._prefix + keyHash; - } - - async clear() { - const promises = []; - for (const key of await Storage.getItemKeysStartingWith(this._prefix)) { - promises.push(await Storage.removeItem(key)); - } - await Promise.all(promises); - } - - -} - -/** - * Set that outsources values to storage. - * The API is similar to the JS Set API, but all methods are async. - */ -export class StorageSet extends StorageWeakSet { - - #size_key?: string - protected get _size_key() { - if (!this.#size_key) this.#size_key = 'dxset.size::'+(this as any)[DX_PTR].idString()+'.'; - return this.#size_key; - } - - #size?: number; - - get size() { - if (this.#size == undefined) throw new Error("size not yet available. use getSize() instead"); - return this.#size; - } - - async getSize() { - if (this.#size != undefined) return this.#size; - else { - await this.#determineSizeFromStorage(); - return this.#size! - } - } - - /** - * Sets this.#size to the correct value determined from storage. - */ - async #determineSizeFromStorage() { - const cachedSize = await Storage.getItem(this._size_key); - const calculatedSize = await Storage.getItemCountStartingWith(this._prefix); - if (cachedSize !== calculatedSize) { - if (cachedSize != undefined) - logger.warn(`Size mismatch for StorageSet (${(this as any)[DX_PTR].idString()}) detected. Setting size to ${calculatedSize}`) - await this.#updateSize(calculatedSize); - } - else this.#size = calculatedSize; - } - - async #updateSize(newSize: number) { - this.#size = newSize; - await Storage.setItem(this._size_key, newSize); - } - - async #incrementSize() { - await this.#updateSize(await this.getSize() + 1); - } - - async #decrementSize() { - await this.#updateSize(await this.getSize() - 1); - } - - - /** - * Appends a new value to the StorageWeakSet. - */ - async add(value: V) { - const storage_key = await this.getStorageKey(value); - if (await this._has(storage_key)) return this; // already exists - await this._add(storage_key, value); - await this.#incrementSize(); - return this; - } - - async delete(value: V) { - const wasDeleted = await super.delete(value); - if (wasDeleted) await this.#decrementSize(); - return wasDeleted; - } - - async clear(): Promise { - await super.clear(); - await this.#updateSize(0); - } - - /** - * Async iterator that returns all keys. - */ - keys() { - return this[Symbol.asyncIterator]() - } - - /** - * Returns an array containing all keys. - * This can be used to iterate over the keys without using a (for await of) loop. - */ - async keysArray() { - const keys = []; - for await (const key of this.keys()) keys.push(key); - return keys; - } - - /** - * Async iterator that returns all values. - */ - values() { - return this[Symbol.asyncIterator]() - } - - /** - * Returns an array containing all values. - * This can be used to iterate over the values without using a (for await of) loop. - */ - async valuesArray() { - const values = []; - for await (const value of this.values()) values.push(value); - return values; - } - - /** - * Async iterator that returns all entries. - */ - entries() { - const self = this; - return (async function*(){ - const keyGenerator = await Storage.getItemKeysStartingWith(self._prefix); - - for (const key of keyGenerator) { - const value = await Storage.getItem(key); - yield (<[V,V]> [value,value]); - } - })() - } - - /** - * Returns an array containing all entries. - * This can be used to iterate over the entries without using a (for await of) loop. - */ - async entriesArray() { - const entries = []; - for await (const entry of this.entries()) entries.push(entry); - return entries; - } - - async *[Symbol.asyncIterator]() { - const keyGenerator = await Storage.getItemKeysStartingWith(this._prefix); - - for (const key of keyGenerator) { - const value = await Storage.getItem(key); - yield ( value); - } - } - -} \ No newline at end of file +// TODO: deprecated module path, remove +export * from "./storage-set.ts"; \ No newline at end of file From 0d46024f336ae4628464a4f01c849f8fa288a78d Mon Sep 17 00:00:00 2001 From: benStre Date: Sat, 3 Feb 2024 00:44:34 +0100 Subject: [PATCH 20/60] add new CommunicationHub, CommunicationInterface classes --- init.ts | 4 + network/client.ts | 3 +- network/communication-hub.ts | 137 +++++++++++ network/communication-interface.ts | 215 ++++++++++++++++-- .../web-socket-client-interface.ts | 116 ++++++++++ .../window-interface.ts | 13 ++ network/supranet.ts | 18 +- runtime/pointers.ts | 2 +- runtime/runtime.ts | 11 +- runtime/storage.ts | 4 +- types/type.ts | 4 +- 11 files changed, 503 insertions(+), 24 deletions(-) create mode 100644 network/communication-hub.ts create mode 100644 network/communication-interfaces/web-socket-client-interface.ts create mode 100644 network/communication-interfaces/window-interface.ts diff --git a/init.ts b/init.ts index 9a33ce6b..47a107e5 100644 --- a/init.ts +++ b/init.ts @@ -12,6 +12,7 @@ import { DX_BOUND_LOCAL_SLOT } from "./runtime/constants.ts"; import { verboseArg } from "./utils/logger.ts"; import { MessageLogger } from "./utils/message_logger.ts"; import { Path } from "./utils/path.ts"; +import { communicationHub } from "./network/communication-hub.ts"; /** @@ -23,6 +24,9 @@ export async function init() { registerStorageAsPointerSource(); // default storage config: + + communicationHub.handler.setDatexInHandler(Runtime.datexIn.bind(Runtime)) + // @ts-ignore NO_INIT if (!globalThis.NO_INIT) { diff --git a/network/client.ts b/network/client.ts index 36a58e81..4d465d5f 100644 --- a/network/client.ts +++ b/network/client.ts @@ -816,6 +816,7 @@ export class InterfaceManager { } // send via indirect connection else if (CommonInterface.isEndpointReachableViaInterface(to)) { + logger.debug("sending to " + to + " via indirect connection"); comInterface = [...CommonInterface.getIndirectInterfacesForEndpoint(to)][0]; // send to first available interface (todo) } @@ -824,7 +825,7 @@ export class InterfaceManager { return InterfaceManager.handleNoRedirectFound(to); } - // prefere proxy_interface + // prefer proxy_interface if (CommonInterface.proxy_interface) comInterface = CommonInterface.proxy_interface; // error: loopback diff --git a/network/communication-hub.ts b/network/communication-hub.ts new file mode 100644 index 00000000..b5831f44 --- /dev/null +++ b/network/communication-hub.ts @@ -0,0 +1,137 @@ +import { dxb_header } from "../utils/global_types.ts"; +import { Endpoint } from "../types/addressing.ts"; +import { CommunicationInterface, CommunicationInterfaceSocket } from "./communication-interface.ts"; +import { Disjunction } from "../types/logic.ts"; +import "../utils/auto_map.ts"; + +export type DatexInData = { + dxb: ArrayBuffer|ReadableStreamDefaultReader, + socket: CommunicationInterfaceSocket +} + +export type DatexOutData = { + dxb: ArrayBuffer, + receivers: Endpoint|Disjunction, // @@any for broadcasts + socket?: CommunicationInterfaceSocket +} + +/** + * Callback for handling incoming datex blocks + */ +export type DatexInHandler = (data: DatexInData) => Promise + +/** + * Public communication access point for managing + * CommunicationInterfaces + */ +export class CommunicationHub { + + // singleton + private constructor() {} + static #instance?: CommunicationHub + static get() { + if (!this.#instance) this.#instance = new CommunicationHub() + return this.#instance; + } + + + public addInterface(comInterface: CommunicationInterface, setAsDefault = false) { + return this.handler.addInterface(comInterface, setAsDefault); + } + + public removeInterface(comInterface: CommunicationInterface) { + return this.handler.removeInterface(comInterface); + } + + + /** + * @private + */ + handler = new CommunicationHubHandler() + +} + + +export const COM_HUB_SECRET = Symbol("COM_HUB_SECRET") + +/** + * Internal handler for managing CommunicationInterfaces + */ +export class CommunicationHubHandler { + + #interfaces = new Set() + #endpointSockets = new Map>().setAutoDefault(Set) + #registeredSockets = new Set() + #defaultSocket?: CommunicationInterfaceSocket + + #datexInHandler?: DatexInHandler + + /** Public facing methods: **/ + public async addInterface(comInterface: CommunicationInterface, setAsDefault = false) { + this.#interfaces.add(comInterface) + await comInterface.init(COM_HUB_SECRET); + if (setAsDefault) this.#defaultSocket = comInterface.sockets.values().next().value + } + + public async removeInterface(comInterface: CommunicationInterface) { + this.#interfaces.delete(comInterface) + await comInterface.deinit(COM_HUB_SECRET); + } + + + /** Internal methods: */ + + public addSocket(socket: CommunicationInterfaceSocket) { + if (!socket.endpoint) throw new Error("Cannot add socket to communication hub without endpoint.") + if (this.#endpointSockets.get(socket.endpoint)?.has(socket)) throw new Error("Cannot add socket to communication hub without endpoint.") + this.#registeredSockets.add(socket) + this.#endpointSockets.getAuto(socket.endpoint).add(socket) + } + + public removeSocket(socket: CommunicationInterfaceSocket) { + if (!socket.endpoint) throw new Error("Cannot remove socket from communication hub without endpoint.") + this.#endpointSockets.getAuto(socket.endpoint).delete(socket) + this.#registeredSockets.delete(socket) + if (this.#endpointSockets.get(socket.endpoint)!.size == 0) this.#endpointSockets.delete(socket.endpoint) + } + + public setDatexInHandler(handler: DatexInHandler) { + this.#datexInHandler = handler + } + + public hasSocket(socket: CommunicationInterfaceSocket) { + return this.#registeredSockets.has(socket) + } + + /** + * Method called by CommunicationInterfaceSockets when they receive a datex block + * @param data + */ + + public datexIn(data: DatexInData) { + if (!this.#datexInHandler) throw new Error("No datexInHandler set") + return this.#datexInHandler(data) + } + + /** + * Method called to send a datex block to a receiver (or as a broadcast) + * @param dxb + */ + public datexOut(data: DatexOutData) { + // ...sendAddressedBlockToReceivers + // ...sendAddressedBlockToReceivers + // ...sendAddressedBlockToReceivers + + // this.#defaultSocket?.sendBlock(Datex.Compiler.compile('?', [keys], {type:ProtocolDataType.HELLO, sign:false, flood:true, __routing_ttl:10})) + } + + public sendAddressedBlockToReceivers(dxb: ArrayBuffer, receiver: Disjunction, destInterface: CommunicationInterface) { + // Compiler... + } + +} + + + + +export const communicationHub = CommunicationHub.get() diff --git a/network/communication-interface.ts b/network/communication-interface.ts index 4ce868b0..8a624155 100644 --- a/network/communication-interface.ts +++ b/network/communication-interface.ts @@ -1,27 +1,124 @@ +import { ProtocolDataType } from "../compiler/protocol_types.ts"; import { Endpoint } from "../types/addressing.ts"; +import { Logger } from "../utils/logger.ts"; +import { COM_HUB_SECRET, communicationHub } from "./communication-hub.ts"; -/** - * Base class for all DATEX communication interfaces - */ -export abstract class CommunicationInterface { - abstract name: string - abstract description?: string +export type InterfaceProperties = { + name: string, + description?: string, + canSend: boolean, + canReceive: boolean, + /** + * Time in milliseconds to wait before reconnecting after a connection error + */ + reconnectInterval?: number, /** - * Can send data + * higher priority interfaces normally provide more bandwidth and are preferred over lower priority interfaces */ - abstract canSend: boolean + priority: number +} +export abstract class CommunicationInterfaceSocket extends EventTarget { /** - * Can receive data + * Endpoint is only set once. If the endpoint changes, a new socket is created */ - abstract canReceive: boolean + #endpoint?: Endpoint + #connected = false + #destroyed = false; + #opened = false; + + interfaceProperties?: InterfaceProperties + + get isRegistered() { + return communicationHub.handler.hasSocket(this) + } + + get connected() { + return this.#connected + } + set connected(connected) { + if (this.#destroyed) throw new Error("Cannot change connected state of destroyed socket.") + this.#connected = connected + this.#updateRegistration(); + } + + get endpoint(): Endpoint|undefined { + return this.#endpoint + } + + set endpoint(endpoint: Endpoint) { + if (this.#endpoint) throw new Error("Cannot change endpoint of socket. Create a new socket instead.") + this.#endpoint = endpoint + this.#updateRegistration(); + } /** - * Has a connection to the supranet, use as a default interface if possible + * Adds or removes the socket from the communication hub based + * on the connection state and endpoint availability */ - abstract isGlobal: boolean // + #updateRegistration() { + // handle open/close + if (this.#opened && !this.#connected) { + this.#opened = false; + this.close() + } + else if (!this.#opened && this.#connected) { + this.open() + this.#opened = true; + } + + + if (!this.#endpoint || this.#destroyed) return; + + if (this.#connected) { + if (!this.isRegistered) { + communicationHub.handler.addSocket(this) + } + } + else { + if (this.isRegistered) { + communicationHub.handler.removeSocket(this) + } + } + } + + public async sendBlock(dxb: ArrayBuffer) { + if (this.#destroyed) throw new Error("Cannot send from destroyed socket.") + if (!this.connected) throw new Error("Cannot send from disconnected socket"); + + const successful = await this.send(dxb) + if (!successful) { + console.error("Failed to send block") + this.connected = false + } + return successful; + } + + protected async receive(dxb: ArrayBuffer) { + console.log("receive",dxb) + if (this.#destroyed) throw new Error("Cannot receive on destroyed socket"); + if (!this.connected) throw new Error("Cannot receive on disconnected socket"); + + const header = await communicationHub.handler.datexIn({ + dxb, + socket: this + }) + + // listen for GOODBYE messages + if (this.endpoint) { + if (header.type == ProtocolDataType.GOODBYE && header.sender === this.endpoint) { + this.connected = false + this.#destroyed = true + this.dispatchEvent(new CustomEvent('endpoint-disconnect')) + } + } + // detect new endpoint + else if (header.sender) { + this.endpoint = header.sender + } + } /** @@ -29,8 +126,100 @@ export abstract class CommunicationInterface { * @param datex * @param to */ - public send(datex:ArrayBuffer, to?: Endpoint) { + protected abstract send(datex:ArrayBuffer): Promise|boolean + + protected abstract open(): void + protected abstract close(): void +} + +/** + * Base class for all DATEX communication interfaces + */ +export abstract class CommunicationInterface { + + protected logger = new Logger(this.constructor.name) + + public sockets = new Set() + + abstract properties: InterfaceProperties + + abstract connect(): boolean|Promise + abstract disconnect(): void|Promise + + #connecting = false; + + /** + * @private + */ + async init(secret: symbol) { + if (secret !== COM_HUB_SECRET) throw new Error("Directly calling CommunicationInterface.init() is not allowed") + await this.#reconnect() + } + + /** + * @private + */ + async deinit(secret: symbol) { + if (secret !== COM_HUB_SECRET) throw new Error("Directly calling CommunicationInterface.deinit() is not allowed") + this.clearSockets() + await this.disconnect() + } + + async #reconnect() { + if (this.#connecting) return; + this.#connecting = true; + while (!await this.connect()) { + await sleep(this.properties.reconnectInterval || 3000) + } + this.logger.success("Connected to " + this.properties.description + " ("+this.properties.name+")"); + this.#connecting = false; + } + + protected async onConnectionError() { + this.logger.error("Connection error (" + this.properties.description + ")"); + this.clearSockets(); + await this.#reconnect() + } + + /** + * Create a new socket for this interface + */ + protected addSocket(socket: Socket) { + this.sockets.add(socket) + socket.connected = true; // adds sockets to communication hub + socket.interfaceProperties = this.properties + socket.addEventListener('endpoint-disconnect', () => { + // remove old socket + this.removeSocket(socket) + // clone and add new socket + const newSocket = this.cloneSocket(socket); + this.addSocket(newSocket); + }) + } + + /** + * Create a new socket from an existing socket + * which is no longer connected to an endpoint + * @param socket + */ + protected abstract cloneSocket(socket: Socket): Socket + + /** + * Remove a socket from this interface + */ + protected removeSocket(socket: Socket) { + this.sockets.delete(socket) + socket.connected = false; // removes socket from communication hub + } + + /** + * Remove all sockets from this interface + */ + protected clearSockets() { + for (const socket of this.sockets) { + this.removeSocket(socket) + } } } \ No newline at end of file diff --git a/network/communication-interfaces/web-socket-client-interface.ts b/network/communication-interfaces/web-socket-client-interface.ts new file mode 100644 index 00000000..a777ea77 --- /dev/null +++ b/network/communication-interfaces/web-socket-client-interface.ts @@ -0,0 +1,116 @@ +import { client_type } from "../../utils/constants.ts"; +import { CommunicationInterface, InterfaceProperties, CommunicationInterfaceSocket } from "../communication-interface.ts"; + + +export class WebSocketClientInterfaceSocket extends CommunicationInterfaceSocket { + constructor(public readonly webSocket: WebSocket) { + super(); + } + + handleReceive = (event: MessageEvent) => { + console.log("receive ws client") + this.receive(event.data) + } + + open() { + console.log("open ws client") + this.webSocket.addEventListener('message', this.handleReceive); + } + + close() { + console.log("close ws client") + this.webSocket.removeEventListener('message', this.handleReceive); + } + + send(datex: ArrayBuffer) { + try { + this.webSocket.send(datex) + return true; + } + catch { + return false; + } + } +} + +export class WebSocketClientInterface extends CommunicationInterface { + + + public origin:URL + private webSocket?: WebSocket; + + public properties: InterfaceProperties = { + name: "web-socket-client", + canSend: true, + canReceive: true, + priority: 10 + } + + constructor(origin: string|URL) { + super() + + // normalize origin + if (typeof origin === "string") { + origin = new URL(origin) + } + if (origin.protocol === "https:") origin.protocol = "wss:" + if (origin.protocol === "http:") origin.protocol = "ws:" + if (origin.protocol !== "wss:" && origin.protocol !== "ws:") { + throw new Error("Invalid protocol for WebSocketClientInterface") + } + + this.origin = origin; + this.properties.description = origin.toString(); + } + + #errorEventListener?: () =>void + #openEventListener?: () =>void + + + connect() { + if (client_type == "browser" && !navigator.onLine) { + this.logger.error("Cannot connect (offline)") + return false; + } + + return new Promise(resolve => { + try { + this.webSocket = new WebSocket(this.origin); + this.webSocket.binaryType = 'arraybuffer'; + + const socket = new WebSocketClientInterfaceSocket(this.webSocket) + + // connection opened + let connectionOpen = false; + this.#errorEventListener = () => { + if (!connectionOpen) resolve(false); + else { + this.onConnectionError(); + } + }; + this.#openEventListener = () => { + if (this.origin.protocol == 'ws' && !this.origin.host.match(/localhost(:\d+)?/)) this.logger.warn(`unsecure websocket connection to ${this.origin.host}`) + this.addSocket(socket); + connectionOpen = true; + resolve(true); + }; + this.webSocket.addEventListener('open', this.#openEventListener); + this.webSocket.addEventListener('error', this.#errorEventListener); + } + catch { + resolve(false) + } + }) + } + + disconnect() { + if (!this.webSocket) return; + if (this.#openEventListener) this.webSocket.removeEventListener('open', this.#openEventListener); + if (this.#errorEventListener) this.webSocket.removeEventListener('error', this.#errorEventListener); + this.webSocket?.close(); + } + + cloneSocket(socket: WebSocketClientInterfaceSocket) { + return new WebSocketClientInterfaceSocket(socket.webSocket); + } +} \ No newline at end of file diff --git a/network/communication-interfaces/window-interface.ts b/network/communication-interfaces/window-interface.ts new file mode 100644 index 00000000..b5814110 --- /dev/null +++ b/network/communication-interfaces/window-interface.ts @@ -0,0 +1,13 @@ +import { CommunicationInterface, CommunicationInterfaceSocket } from "../communication-interface.ts"; + + +export class WindowInterfaceSocket extends CommunicationInterfaceSocket { + +} + +export class WindowInterface extends CommunicationInterface { + constructor() { + super() + this.sockets.add(new WindowInterfaceSocket()) + } +} \ No newline at end of file diff --git a/network/supranet.ts b/network/supranet.ts index 273237e9..64d5ea04 100644 --- a/network/supranet.ts +++ b/network/supranet.ts @@ -76,6 +76,8 @@ export class Supranet { return true; } + const alreadyConnected = this.#connected; + // load runtime, own endpoint, nodes this.#connected = false; endpoint = await this.init(endpoint, local_cache, sign_keys, enc_keys) @@ -93,10 +95,18 @@ export class Supranet { return true; } - const connected = await this._connect(via_node, !shouldSwitchInstance); - if (shouldSwitchInstance) await this.handleSwitchToInstance() + if (alreadyConnected) { + this.#connected = true; + this.sayHelloToAllInterfaces(); + if (shouldSwitchInstance) await this.handleSwitchToInstance(); + return true; + } + else { + const connected = await this._connect(via_node, !shouldSwitchInstance); + if (shouldSwitchInstance) await this.handleSwitchToInstance() + return connected; + } - return connected; } private static sayHelloToAllInterfaces() { @@ -107,7 +117,7 @@ export class Supranet { private static shouldSwitchInstance(endpoint: Endpoint) { // return false; - return (endpoint.main === endpoint || Runtime.getActiveLocalStorageEndpoints().includes(endpoint)) && Runtime.Blockchain + return (endpoint.main === endpoint || Runtime.getActiveLocalStorageEndpoints().includes(endpoint)) && (!!Runtime.Blockchain) } /** diff --git a/runtime/pointers.ts b/runtime/pointers.ts index c23dce17..102dee30 100644 --- a/runtime/pointers.ts +++ b/runtime/pointers.ts @@ -29,7 +29,7 @@ import { IterableWeakMap } from "../utils/iterable-weak-map.ts"; import { LazyPointer } from "./lazy-pointer.ts"; import { ReactiveArrayMethods } from "../types/reactive-methods/array.ts"; import { Assertion } from "../types/assertion.ts"; -import { StorageSet } from "../types/storage_set.ts"; +import { StorageSet } from "../types/storage-set.ts"; import { Storage } from "./storage.ts"; export type observe_handler = (value:V extends RefLike ? T : V, key?:K, type?:Ref.UPDATE_TYPE, transform?:boolean, is_child_update?:boolean, previous?: any, atomic_id?:symbol)=>void|boolean diff --git a/runtime/runtime.ts b/runtime/runtime.ts index 1ae7e4ab..71c494d2 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -62,6 +62,7 @@ import { Conjunction, Disjunction, Logical, Negation } from "../types/logic.ts"; import { Logger } from "../utils/logger.ts"; import { Debugger } from "./debugger.ts"; import {decompile as wasm_decompile} from "../wasm/adapter/pkg/datex_wasm.js"; +import { CommunicationInterfaceSocket } from "../network/communication-interface.ts"; import "../types/native_types.ts"; // load prototype overrides import { Time } from "../types/time.ts"; @@ -75,6 +76,7 @@ import { sendDatexViaHTTPChannel } from "../network/datex-http-channel.ts"; import { deleteCookie, getCookie, setCookie } from "../utils/cookies.ts"; import { addPersistentListener, removePersistentListener } from "../utils/persistent-listeners.ts"; import { endpoint_config } from "./endpoint_config.ts"; +import { DatexInData } from "../network/communication-hub.ts"; const mime = client_type === "deno" ? (await import("https://deno.land/x/mimetypes@v1.0.0/mod.ts")).mime : null; @@ -1676,6 +1678,13 @@ export class Runtime { return handler; } + public static datexIn(data: DatexInData) { + if (data.dxb instanceof ArrayBuffer) return this.handleDatexIn(data.dxb, data.socket.endpoint, undefined, undefined, undefined, data.socket); + else if (data.dxb instanceof ReadableStreamDefaultReader) return this.handleContinuousBlockStream(data.dxb, undefined, undefined, undefined, data.socket.endpoint, data.socket) + else throw new Error("Invalid data for datexIn") + } + + // extract dxb blocks from a continuos stream private static async handleContinuousBlockStream(dxb_stream_reader: ReadableStreamDefaultReader, full_scope_callback, variables?:any, header_callback?:(header:dxb_header)=>void, last_endpoint?:Endpoint, source?:Source) { @@ -1847,7 +1856,7 @@ export class Runtime { * @param header_callback callback method returning information for the evaluated header before executing the dxb * @returns header information (after executing the dxb) */ - private static async handleDatexIn(dxb:ArrayBuffer, last_endpoint:Endpoint, full_scope_callback?:(sid:number, scope:any, error?:boolean)=>void, _?:any, header_callback?:(header:dxb_header)=>void, source?: Source): Promise { + private static async handleDatexIn(dxb:ArrayBuffer, last_endpoint?:Endpoint, full_scope_callback?:(sid:number, scope:any, error?:boolean)=>void, _?:any, header_callback?:(header:dxb_header)=>void, source?: CommunicationInterfaceSocket): Promise { let header:dxb_header, data_uint8:Uint8Array; diff --git a/runtime/storage.ts b/runtime/storage.ts index 50c6a034..b5315ccb 100644 --- a/runtime/storage.ts +++ b/runtime/storage.ts @@ -13,8 +13,8 @@ import { Type } from "../types/type.ts"; import { addPersistentListener } from "../utils/persistent-listeners.ts"; import { Endpoint, LOCAL_ENDPOINT } from "../types/addressing.ts"; import { ESCAPE_SEQUENCES } from "../utils/logger.ts"; -import { StorageMap } from "../types/storage_map.ts"; -import { StorageSet } from "../types/storage_set.ts"; +import { StorageMap } from "../types/storage-map.ts"; +import { StorageSet } from "../types/storage-set.ts"; import { IterableWeakSet } from "../utils/iterable-weak-set.ts"; import { LazyPointer } from "./lazy-pointer.ts"; diff --git a/types/type.ts b/types/type.ts index cc28620f..f04fcc84 100644 --- a/types/type.ts +++ b/types/type.ts @@ -19,8 +19,8 @@ import { Time } from "./time.ts"; import type { Task } from "./task.ts"; import { Assertion } from "./assertion.ts"; import type { Iterator } from "./iterator.ts"; -import {StorageMap, StorageWeakMap} from "./storage_map.ts" -import {StorageSet, StorageWeakSet} from "./storage_set.ts" +import {StorageMap, StorageWeakMap} from "./storage-map.ts" +import {StorageSet, StorageWeakSet} from "./storage-set.ts" import { ExtensibleFunction } from "./function-utils.ts"; import type { JSTransferableFunction } from "./js-function.ts"; From 51a5cbaa523e625e59de14b58e94a5a0dee9f1ab Mon Sep 17 00:00:00 2001 From: benStre Date: Sat, 3 Feb 2024 21:53:31 +0100 Subject: [PATCH 21/60] more refactoring --- .vscode/settings.json | 5 - init.ts | 17 +- network/client.ts | 2 +- network/communication-hub.ts | 248 ++++++++++++++++-- network/communication-interface.ts | 75 +++++- .../local-loopback-interface.ts | 60 +++++ .../web-socket-client-interface.ts | 10 +- .../window-interface.ts | 159 ++++++++++- runtime/runtime.ts | 99 ++++--- types/addressing.ts | 2 +- 10 files changed, 573 insertions(+), 104 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 network/communication-interfaces/local-loopback-interface.ts diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index cc0744bb..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "deno.enable": true, - "deno.unstable": true, - "deno.lint": true -} \ No newline at end of file diff --git a/init.ts b/init.ts index 47a107e5..16210a38 100644 --- a/init.ts +++ b/init.ts @@ -13,7 +13,7 @@ import { verboseArg } from "./utils/logger.ts"; import { MessageLogger } from "./utils/message_logger.ts"; import { Path } from "./utils/path.ts"; import { communicationHub } from "./network/communication-hub.ts"; - +import { LocalLoopbackInterface } from "./network/communication-interfaces/local-loopback-interface.ts"; /** * Runtime init (sets ENV, storage, endpoint, ...) @@ -22,10 +22,11 @@ export async function init() { // register DatexStorage as pointer source registerStorageAsPointerSource(); - // default storage config: - + // bind communication hub handlers to runtime communicationHub.handler.setDatexInHandler(Runtime.datexIn.bind(Runtime)) + Runtime.setDatexOutHandler(communicationHub.handler.datexOut.bind(communicationHub.handler)) + await communicationHub.addInterface(new LocalLoopbackInterface()) // @ts-ignore NO_INIT if (!globalThis.NO_INIT) { @@ -107,8 +108,8 @@ export async function init() { await Runtime.precompile(); // set Runtime ENV (not persistent if globalThis.NO_INIT) - Runtime.ENV = globalThis.NO_INIT ? getDefaultEnv() : await Storage.loadOrCreate("Datex.Runtime.ENV", getDefaultEnv); - Runtime.ENV[DX_BOUND_LOCAL_SLOT] = "env" + Runtime.ENV = (globalThis as any).NO_INIT ? getDefaultEnv() : await Storage.loadOrCreate("Datex.Runtime.ENV", getDefaultEnv); + (Runtime.ENV as any)[DX_BOUND_LOCAL_SLOT] = "env" // workaround, should never happen if (!Runtime.ENV) { @@ -132,8 +133,8 @@ export async function init() { function getDefaultEnv() { return { - LANG: globalThis.localStorage?.lang ?? globalThis?.navigator?.language?.split("-")[0]?.split("_")[0] ?? 'en', - DATEX_VERSION: null + LANG: globalThis.localStorage?.lang as string ?? globalThis?.navigator?.language?.split("-")[0]?.split("_")[0] ?? 'en', + DATEX_VERSION: "" } } @@ -142,7 +143,7 @@ export async function init() { Runtime.persistent_memory = (await Storage.loadOrCreate("Datex.Runtime.MEMORY", ()=>new Map())).setAutoDefault(Object); - if (!globalThis.NO_INIT) { + if (!(globalThis as any).NO_INIT) { Runtime.init(); // @ts-ignore diff --git a/network/client.ts b/network/client.ts index 4d465d5f..1e6d99e4 100644 --- a/network/client.ts +++ b/network/client.ts @@ -690,7 +690,7 @@ export class InterfaceManager { // datex out is now redirected to this interface public static enable(){ if (this.enabled) return; - Runtime.setDatexOut(InterfaceManager.send); + // Runtime.setDatexOut(InterfaceManager.send); this.enabled = true; } diff --git a/network/communication-hub.ts b/network/communication-hub.ts index b5831f44..69125258 100644 --- a/network/communication-hub.ts +++ b/network/communication-hub.ts @@ -1,8 +1,13 @@ import { dxb_header } from "../utils/global_types.ts"; import { Endpoint } from "../types/addressing.ts"; -import { CommunicationInterface, CommunicationInterfaceSocket } from "./communication-interface.ts"; +import { CommunicationInterface, CommunicationInterfaceSocket, ConnectedCommunicationInterfaceSocket } from "./communication-interface.ts"; import { Disjunction } from "../types/logic.ts"; import "../utils/auto_map.ts"; +import { InterfaceDirection } from "./communication-interface.ts"; +import { ESCAPE_SEQUENCES, Logger } from "../utils/logger.ts"; +import { Datex } from "../mod.ts"; +import { NetworkError } from "../types/errors.ts"; +import { Compiler } from "../compiler/compiler.ts"; export type DatexInData = { dxb: ArrayBuffer|ReadableStreamDefaultReader, @@ -34,7 +39,6 @@ export class CommunicationHub { return this.#instance; } - public addInterface(comInterface: CommunicationInterface, setAsDefault = false) { return this.handler.addInterface(comInterface, setAsDefault); } @@ -44,6 +48,11 @@ export class CommunicationHub { } + public printStatus() { + return this.handler.printStatus(); + } + + /** * @private */ @@ -58,19 +67,29 @@ export const COM_HUB_SECRET = Symbol("COM_HUB_SECRET") * Internal handler for managing CommunicationInterfaces */ export class CommunicationHubHandler { + + #logger = new Logger("CommunicationHub") #interfaces = new Set() - #endpointSockets = new Map>().setAutoDefault(Set) - #registeredSockets = new Set() - #defaultSocket?: CommunicationInterfaceSocket + // CommunicationInterfaceSockets are ordered, most recent last + #endpointSockets = new Map>().setAutoDefault(Set) + #registeredSockets = new Map>().setAutoDefault(Set) + #defaultSocket?: ConnectedCommunicationInterfaceSocket #datexInHandler?: DatexInHandler + directionSymbols = { + [InterfaceDirection.IN]: "◀──", + [InterfaceDirection.OUT]: "──▶", + [InterfaceDirection.IN_OUT]: "◀─▶" + } + + /** Public facing methods: **/ public async addInterface(comInterface: CommunicationInterface, setAsDefault = false) { this.#interfaces.add(comInterface) await comInterface.init(COM_HUB_SECRET); - if (setAsDefault) this.#defaultSocket = comInterface.sockets.values().next().value + if (setAsDefault) this.#defaultSocket = comInterface.getSockets().values().next().value } public async removeInterface(comInterface: CommunicationInterface) { @@ -78,21 +97,114 @@ export class CommunicationHubHandler { await comInterface.deinit(COM_HUB_SECRET); } + public printStatus() { + let string = ""; + string += "DATEX Communication Hub\n" + string += ` Local Endpoint: ${Datex.Runtime.endpoint}\n` + string += ` ${this.#interfaces.size} interfaces registered\n` + string += ` ${this.#registeredSockets.size} sockets connected\n\n` + + const mapping = new Map>() + + // interfaces with direct sockets + for (const comInterface of this.#interfaces) { + const sockets = new Set( + [...comInterface.getSockets()] + .map(socket => [socket.endpoint, socket] as [Endpoint, CommunicationInterfaceSocket]) + ) + const identifier = comInterface.toString() + if (mapping.has(identifier)) { + sockets.forEach(([endpoint, socket]) => mapping.get(identifier)!.add([endpoint, socket])) + } + else mapping.set(identifier, sockets) + } + + // indirect connections + for (const [endpoint, sockets] of this.#endpointSockets) { + for (const socket of sockets) { + // check if endpoint is indirect + if (socket.endpoint !== endpoint) { + if (!socket.interfaceProperties) { + console.warn("Invalid socket, missing interfaceProperties", socket); + continue; + } + const identifier = socket.toString(); + if (mapping.has(identifier)) { + mapping.get(identifier)!.add([endpoint, socket]) + } + else mapping.set(identifier, new Set([[endpoint, socket]])) + } + } + } + + string += "Default socket: " + (this.#defaultSocket ? this.#defaultSocket.toString() : "none") + "\n"; + + + // print + for (const [identifier, sockets] of mapping) { + string += `\n${identifier}\n` + for (const [endpoint, socket] of sockets) { + const directionSymbol = this.directionSymbols[socket.interfaceProperties?.direction as InterfaceDirection] ?? "?" + const isDirect = socket.endpoint === endpoint; + const color = socket.connected ? + ( + socket.endpoint ? + ESCAPE_SEQUENCES.UNYT_GREEN : + ESCAPE_SEQUENCES.UNYT_GREY + ) : + ESCAPE_SEQUENCES.UNYT_RED + const connectedState = `${color}⬤${ESCAPE_SEQUENCES.RESET}` + string += ` ${connectedState} ${directionSymbol}${isDirect?'':' (indirect)'} ${endpoint??'unknown endpoint'}\n` + } + } + + console.log(string) + + } /** Internal methods: */ - public addSocket(socket: CommunicationInterfaceSocket) { - if (!socket.endpoint) throw new Error("Cannot add socket to communication hub without endpoint.") - if (this.#endpointSockets.get(socket.endpoint)?.has(socket)) throw new Error("Cannot add socket to communication hub without endpoint.") - this.#registeredSockets.add(socket) - this.#endpointSockets.getAuto(socket.endpoint).add(socket) + public registerSocket(socket: ConnectedCommunicationInterfaceSocket, endpoint: Endpoint|undefined = socket.endpoint) { + if (!endpoint) throw new Error("Cannot register socket to communication hub without endpoint.") + if (this.#endpointSockets.get(endpoint)?.has(socket)) throw new Error("Cannot register socket to communication hub without endpoint.") + if (!socket.connected || !socket.endpoint || !socket.interfaceProperties) throw new Error("Cannot register disconnected or uninitialized socket.") + + this.#logger.debug("Added new" + (socket.endpoint==endpoint?'':' indirect') + " socket " + socket.toString() + " for endpoint " + endpoint.toString()) + this.#registeredSockets.getAuto(socket).add(endpoint); + this.#endpointSockets.getAuto(endpoint).add(socket); + this.sortSockets(endpoint) } - public removeSocket(socket: CommunicationInterfaceSocket) { - if (!socket.endpoint) throw new Error("Cannot remove socket from communication hub without endpoint.") - this.#endpointSockets.getAuto(socket.endpoint).delete(socket) - this.#registeredSockets.delete(socket) - if (this.#endpointSockets.get(socket.endpoint)!.size == 0) this.#endpointSockets.delete(socket.endpoint) + public unregisterSocket(socket: CommunicationInterfaceSocket, endpoint: Endpoint|undefined = socket.endpoint) { + const connectedSocket = socket as ConnectedCommunicationInterfaceSocket; + if (!endpoint) throw new Error("Cannot unregister socket from communication hub without endpoint.") + if (!this.#endpointSockets.has(endpoint)) throw new Error("Cannot unregister socket, not registered for endpoint.") + if (!this.#registeredSockets.has(connectedSocket)) throw new Error("Cannot unregister socket, not registered.") + + // remove default socket + if (connectedSocket === this.#defaultSocket) this.#defaultSocket = undefined; + + const isDirect = connectedSocket.endpoint==endpoint; + + this.#logger.debug("Removed" + (isDirect?'':' indirect') + " socket " + connectedSocket.toString() + " for endpoint " + endpoint.toString()) + + const endpointSockets = this.#endpointSockets.get(endpoint)!; + const socketEndpoints = this.#registeredSockets.get(connectedSocket)!; + + // remove own socket endpoint + endpointSockets.delete(connectedSocket) + socketEndpoints.delete(endpoint) + + // direct socket removed, also remove all indirect sockets + if (isDirect) { + for (const indirectEndpoint of socketEndpoints) { + this.#endpointSockets.get(indirectEndpoint)?.delete(connectedSocket) + } + this.#registeredSockets.delete(connectedSocket) + } + + if (endpointSockets.size == 0) this.#endpointSockets.delete(endpoint) + if (socketEndpoints.size == 0) this.#registeredSockets.delete(connectedSocket) } public setDatexInHandler(handler: DatexInHandler) { @@ -100,7 +212,7 @@ export class CommunicationHubHandler { } public hasSocket(socket: CommunicationInterfaceSocket) { - return this.#registeredSockets.has(socket) + return this.#registeredSockets.has(socket as ConnectedCommunicationInterfaceSocket) } /** @@ -113,25 +225,109 @@ export class CommunicationHubHandler { return this.#datexInHandler(data) } + /** + * Sort available sockets for endpoint by priority and connectTimestamp + * @param endpoint + */ + private sortSockets(endpoint: Endpoint) { + const sockets = this.#endpointSockets.get(endpoint) + if (!sockets) throw new Error("No sockets for endpoint " + endpoint); + const sortedSockets = new Set( + Object + // group by priority + .entries(Object.groupBy(sockets, socket => socket.interfaceProperties.priority)) + // sort by priority + .sort(([a], [b]) => Number(b) - Number(a)) + // sort by connectTimestamp in each priority group + .map(([priority, sockets]) => [priority, sockets!.toSorted( + (a, b) => b.connectTimestamp - a.connectTimestamp + )] as const) + // flatten + .flatMap(([_, sockets]) => sockets) + ) + this.#endpointSockets.set(endpoint, sortedSockets) + } + + private getPreferredSocketForEndpoint(endpoint: Endpoint, excludeSocket?: CommunicationInterfaceSocket) { + + for (const socket of this.#endpointSockets.get(endpoint) ?? []) { + if (socket === excludeSocket) continue; + return socket; + } + + if (this.#defaultSocket !== excludeSocket) + return this.#defaultSocket; + } + + + /** * Method called to send a datex block to a receiver (or as a broadcast) * @param dxb */ - public datexOut(data: DatexOutData) { - // ...sendAddressedBlockToReceivers - // ...sendAddressedBlockToReceivers - // ...sendAddressedBlockToReceivers + public async datexOut(data: DatexOutData):Promise { + + // broadcast + if (data.receivers == Datex.BROADCAST) return this.datexBroadcastOut(data); + + const receivers = data.receivers instanceof Endpoint ? [data.receivers] : [...data.receivers]; + const outGroups = new Map( + // group receivers by socket + [...Map.groupBy( + // map receivers to sockets + receivers.map(r => ({endpoint: r, socket: this.getPreferredSocketForEndpoint(r)}), + ), ({socket}) => socket) + .entries() + ] + // map endpoint object arrays to Set + .map(([k, v]) => [k, new Disjunction(...v.map(({endpoint}) => endpoint))] as const) + ); + + + const promises = [] + + for (const [socket, endpoints] of outGroups) { + const endpointsString = [...endpoints].map(e => e.toString()).join(", ") + if (!socket) continue; + this.#logger.debug("sending to " + endpointsString + " ("+socket.toString()+")"); + promises.push(this.sendAddressedBlockToReceivers(data.dxb, endpoints, socket)); + } + + // throw error if message could not be sent to some receivers + if (outGroups.has(undefined)) { + const endpointsString = [...outGroups.get(undefined)!].map(e => e.toString()).join(", ") + throw new NetworkError("No socket for endpoints " + endpointsString); + } + + await Promise.all(promises); + } + + public datexBroadcastOut(data: DatexOutData) { + const reachedEndpoints = new Set() - // this.#defaultSocket?.sendBlock(Datex.Compiler.compile('?', [keys], {type:ProtocolDataType.HELLO, sign:false, flood:true, __routing_ttl:10})) + for (const [socket] of this.#registeredSockets) { + if (data.socket === socket) continue; + if (reachedEndpoints.has(socket.endpoint)) continue; + reachedEndpoints.add(socket.endpoint); + + socket.sendBlock(data.dxb); + } } - public sendAddressedBlockToReceivers(dxb: ArrayBuffer, receiver: Disjunction, destInterface: CommunicationInterface) { - // Compiler... + public async sendAddressedBlockToReceivers(dxb: ArrayBuffer, receivers: Disjunction, destSocket: CommunicationInterfaceSocket) { + const addressdDXB = Compiler.updateHeaderReceiver(dxb, receivers); + if (!addressdDXB) throw new Error("Failed to update header receivers"); + const success = await destSocket.sendBlock(addressdDXB); + if (!success) { + return this.datexOut({ + dxb, + receivers, + socket: destSocket + }) + } } } - - export const communicationHub = CommunicationHub.get() diff --git a/network/communication-interface.ts b/network/communication-interface.ts index 8a624155..2b9eca4b 100644 --- a/network/communication-interface.ts +++ b/network/communication-interface.ts @@ -1,15 +1,21 @@ import { ProtocolDataType } from "../compiler/protocol_types.ts"; +import { LOCAL_ENDPOINT, Runtime } from "../datex_all.ts"; import { Endpoint } from "../types/addressing.ts"; import { Logger } from "../utils/logger.ts"; import { COM_HUB_SECRET, communicationHub } from "./communication-hub.ts"; +export enum InterfaceDirection { + IN, + OUT, + IN_OUT +} + export type InterfaceProperties = { - name: string, - description?: string, + type: string, + name?: string, - canSend: boolean, - canReceive: boolean, + direction: InterfaceDirection, /** * Time in milliseconds to wait before reconnecting after a connection error */ @@ -20,6 +26,11 @@ export type InterfaceProperties = { priority: number } +function getIdentifier(properties?: InterfaceProperties) { + if (!properties) return "unknown"; + return `${properties.type}${properties.name? ` (${properties.name})` : ''}` +} + export abstract class CommunicationInterfaceSocket extends EventTarget { /** * Endpoint is only set once. If the endpoint changes, a new socket is created @@ -29,6 +40,12 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { #destroyed = false; #opened = false; + #connectTimestamp = Date.now() + + get connectTimestamp() { + return this.#connectTimestamp + } + interfaceProperties?: InterfaceProperties get isRegistered() { @@ -74,17 +91,19 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { if (this.#connected) { if (!this.isRegistered) { - communicationHub.handler.addSocket(this) + this.#connectTimestamp = Date.now() + communicationHub.handler.registerSocket(this as ConnectedCommunicationInterfaceSocket) } } else { if (this.isRegistered) { - communicationHub.handler.removeSocket(this) + communicationHub.handler.unregisterSocket(this) } } } public async sendBlock(dxb: ArrayBuffer) { + if (this.interfaceProperties?.direction === InterfaceDirection.IN) throw new Error("Cannot send from an IN interface socket"); if (this.#destroyed) throw new Error("Cannot send from destroyed socket.") if (!this.connected) throw new Error("Cannot send from disconnected socket"); @@ -98,6 +117,7 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { protected async receive(dxb: ArrayBuffer) { console.log("receive",dxb) + if (this.interfaceProperties?.direction === InterfaceDirection.OUT) throw new Error("Cannot receive on an OUT interface socket"); if (this.#destroyed) throw new Error("Cannot receive on destroyed socket"); if (!this.connected) throw new Error("Cannot receive on disconnected socket"); @@ -113,6 +133,10 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { this.#destroyed = true this.dispatchEvent(new CustomEvent('endpoint-disconnect')) } + // message from another endpoint, record as indirect socket connection + else if (header.sender !== this.endpoint) { + communicationHub.handler.registerSocket(this as ConnectedCommunicationInterfaceSocket, header.sender) + } } // detect new endpoint else if (header.sender) { @@ -130,8 +154,25 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { protected abstract open(): void protected abstract close(): void + + toString() { + return getIdentifier(this.interfaceProperties) + } } +/** + * A connected communication interface socket that is registered in the communication hub + * and can be used to send and receive messages + */ +export type ConnectedCommunicationInterfaceSocket = CommunicationInterfaceSocket & { + connected: true, + endpoint: Endpoint, + interfaceProperties: InterfaceProperties +} + + +type ReadonlySet = Set & {add: never, delete: never, clear: never} + /** * Base class for all DATEX communication interfaces @@ -140,7 +181,7 @@ export abstract class CommunicationInterface() + #sockets = new Set() abstract properties: InterfaceProperties @@ -154,6 +195,7 @@ export abstract class CommunicationInterface { + return this.#sockets as ReadonlySet + } + async #reconnect() { if (this.#connecting) return; this.#connecting = true; while (!await this.connect()) { await sleep(this.properties.reconnectInterval || 3000) } - this.logger.success("Connected to " + this.properties.description + " ("+this.properties.name+")"); + this.logger.success("Connected to " + this); this.#connecting = false; } protected async onConnectionError() { - this.logger.error("Connection error (" + this.properties.description + ")"); + this.logger.error("Connection error (" + this + ")"); this.clearSockets(); await this.#reconnect() } @@ -186,9 +232,8 @@ export abstract class CommunicationInterface { // remove old socket this.removeSocket(socket) @@ -196,6 +241,7 @@ export abstract class CommunicationInterface { + + #currentSocket?: LocalLoopbackInterfaceSocket + + public properties: InterfaceProperties = { + type: "local", + direction: InterfaceDirection.OUT, + priority: 100 + } + + constructor() { + super(); + } + + connect() { + // default @@local socket (never removed) + this.createSocket(LOCAL_ENDPOINT); + + Runtime.onEndpointChanged((endpoint) => { + // remove socket for previous endpoint + if (this.#currentSocket) this.removeSocket(this.#currentSocket) + // add new socket for endpoint + this.#currentSocket = this.createSocket(endpoint); + }) + + return true; + } + disconnect() {} + + private createSocket(endpoint: Endpoint) { + const socket = new LocalLoopbackInterfaceSocket(); + socket.endpoint = endpoint; + this.addSocket(socket) + return socket; + } + + cloneSocket(_socket: LocalLoopbackInterfaceSocket): never { + throw new Error("LocalLoopbackInterface does not support cloning") + } + +} \ No newline at end of file diff --git a/network/communication-interfaces/web-socket-client-interface.ts b/network/communication-interfaces/web-socket-client-interface.ts index a777ea77..957d22fc 100644 --- a/network/communication-interfaces/web-socket-client-interface.ts +++ b/network/communication-interfaces/web-socket-client-interface.ts @@ -1,4 +1,5 @@ import { client_type } from "../../utils/constants.ts"; +import { InterfaceDirection } from "../communication-interface.ts"; import { CommunicationInterface, InterfaceProperties, CommunicationInterfaceSocket } from "../communication-interface.ts"; @@ -40,10 +41,9 @@ export class WebSocketClientInterface extends CommunicationInterfacevoid diff --git a/network/communication-interfaces/window-interface.ts b/network/communication-interfaces/window-interface.ts index b5814110..b7c92d30 100644 --- a/network/communication-interfaces/window-interface.ts +++ b/network/communication-interfaces/window-interface.ts @@ -1,13 +1,166 @@ -import { CommunicationInterface, CommunicationInterfaceSocket } from "../communication-interface.ts"; +import { Runtime } from "../../runtime/runtime.ts"; +import { Endpoint, Target } from "../../types/addressing.ts"; +import { CommunicationInterface, CommunicationInterfaceSocket, InterfaceDirection, InterfaceProperties } from "../communication-interface.ts"; export class WindowInterfaceSocket extends CommunicationInterfaceSocket { + constructor(public readonly window: Window, public readonly windowOrigin: string) { + super(); + } + + handleReceive = (event: MessageEvent) => { + console.log("receive window client") + if (event.origin == this.windowOrigin && event.data instanceof ArrayBuffer) { + this.receive(event.data) + } + } + + open() { + console.log("open window client") + globalThis.addEventListener('message', this.handleReceive); + } + close() { + console.log("close window client") + globalThis.removeEventListener('message', this.handleReceive); + } + + send(dxb: ArrayBuffer) { + try { + this.window.postMessage(dxb, this.windowOrigin) + return true; + } + catch { + return false; + } + } } export class WindowInterface extends CommunicationInterface { - constructor() { + + #window: Window + #windowOrigin: string + #isChild: boolean + + public properties: InterfaceProperties = { + type: "window", + direction: InterfaceDirection.IN_OUT, + priority: 10 + } + + constructor(window: Window, windowOrigin?: string|URL) { super() - this.sockets.add(new WindowInterfaceSocket()) + + const windowOriginURL = windowOrigin ? new URL(windowOrigin) : null; + + this.#window = window; + + // is the child + if (window === self.window.opener) { + this.#isChild = true; + + // explicitly set window origin + if (windowOriginURL) { + this.#windowOrigin = windowOriginURL.origin; + } + else { + // first try window.location.origin + try { + this.#windowOrigin = window.location.origin; + } + // try document.referrer + catch { + if (!document.referrer) throw new Error("The origin of the parent window cannot be determined automatically. Please provide windowOrigin as second argument."); + this.#windowOrigin = new URL(document.referrer).origin; + } + } + this.logger.info("initializing as child window, parent window origin: " + this.#windowOrigin) + } + // is the parent document + else { + this.#isChild = false; + + // explicitly set window origin + if (windowOriginURL) { + this.#windowOrigin = windowOriginURL.origin; + } + else { + throw new Error("The origin of the child window cannot be determined automatically. Please provide windowOrigin as second argument."); + } + this.logger.info("initializing as parent window, window origin: " + this.#windowOrigin) + } + + this.properties.name = windowOriginURL?.toString() || this.#windowOrigin; + + globalThis.addEventListener("message", this.onReceive); + if (this.#isChild) { + // if in sub window: send INIT to parent immediately + this.sendInit(); + } } + + connect() { + return true; + } + + disconnect() { + // make sure event listener is removed if INIT not yet completed + globalThis.removeEventListener("message", this.onReceive); + } + + + private sendInit() { + this.#window.postMessage({ + type: "INIT", + endpoint: Runtime.endpoint.toString() + }, this.#windowOrigin); + } + + private onReceive = (event: MessageEvent) => { + if (event.origin == this.#windowOrigin) { + const data = event.data; + + // receive as parent + if (data?.type == "INIT") { + globalThis.removeEventListener("message", this.onReceive); + + const socket = new WindowInterfaceSocket(this.#window, this.#windowOrigin) + socket.endpoint = Target.get(data.endpoint) as Endpoint; + this.addSocket(socket) + // if in parent: send INIT to window after initialized + if (!this.#isChild) this.sendInit(); + } + } + } + + cloneSocket(socket: WindowInterfaceSocket) { + return new WindowInterfaceSocket(socket.window, socket.windowOrigin); + } + + + static createChildInterface(childWindow: Window, windowOrigin: string|URL) { + return new WindowInterface(childWindow, windowOrigin) + } + + static createParentInterface(parentWindow: Window, windowOrigin?: string|URL) { + return new WindowInterface(parentWindow, windowOrigin) + } + + /** + * Open a new window and attaches a WindowInterface + * The interface must still be added to the communication hub with `communicationHub.addInterface(window.interface)` + */ + static openWindow(url: string | URL, target?: string, features?: string) { + const newWindow = window.open(url, target, features); + if (!newWindow) return { + window: null, + windowInterface: null + }; + const windowInterface = this.createChildInterface(newWindow, url) + return { + window: newWindow, + windowInterface + }; + } + } \ No newline at end of file diff --git a/runtime/runtime.ts b/runtime/runtime.ts index 71c494d2..c1c384f3 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -28,7 +28,7 @@ Symbol.prototype.toJSON = function(){return globalThis.String(this)} /***** imports */ import { Compiler, compiler_options, PrecompiledDXB, ProtocolDataTypesMap, DatexResponse} from "../compiler/compiler.ts"; // Compiler functions import { Pointer, PointerProperty, RefOrValue, Ref, ObjectWithDatexValues, JSValueWith$, MinimalJSRef, ObjectRef, RefLike, UpdateScheduler} from "./pointers.ts"; -import { Endpoint, endpoints, IdEndpoint, LOCAL_ENDPOINT, Target, target_clause, WildcardTarget } from "../types/addressing.ts"; +import { BROADCAST, Endpoint, endpoints, IdEndpoint, LOCAL_ENDPOINT, Target, target_clause, WildcardTarget } from "../types/addressing.ts"; import { RuntimePerformance } from "./performance_measure.ts"; import { NetworkError, PermissionError, PointerError, RuntimeError, SecurityError, ValueError, Error as DatexError, CompilerError, TypeError, SyntaxError, AssertionError } from "../types/errors.ts"; import { Function as DatexFunction } from "../types/function.ts"; @@ -76,7 +76,7 @@ import { sendDatexViaHTTPChannel } from "../network/datex-http-channel.ts"; import { deleteCookie, getCookie, setCookie } from "../utils/cookies.ts"; import { addPersistentListener, removePersistentListener } from "../utils/persistent-listeners.ts"; import { endpoint_config } from "./endpoint_config.ts"; -import { DatexInData } from "../network/communication-hub.ts"; +import type { DatexInData, DatexOutData } from "../network/communication-hub.ts"; const mime = client_type === "deno" ? (await import("https://deno.land/x/mimetypes@v1.0.0/mod.ts")).mime : null; @@ -505,29 +505,31 @@ export class Runtime { private static local_input_handler = Runtime.getDatexInputHandler(); // default datex out: send to self (if no routing available) - private static datex_out:(dxb:ArrayBuffer, to?:Endpoint, flood?:boolean, source?:Source)=>Promise = async (dxb, to, flood, source)=>{ - // external datex out request, but this is the default interface (only access to local endpoint) - if (!(to instanceof Endpoint && Runtime.endpoint.equals(to))) { + private static datex_out:(data: DatexOutData)=>Promise = async (data)=>{ + // directly redirect to local input + const receiver = data.receivers instanceof Endpoint ? data.receivers : (data.receivers.size == 1 ? [...data.receivers][0] : undefined); + if (!(receiver instanceof Endpoint && Runtime.endpoint.equals(receiver))) { + this.local_input_handler(data.dxb); throw new NetworkError(DATEX_ERROR.NO_EXTERNAL_CONNECTION) } - // directly redirect to local input - else this.local_input_handler(dxb); + // external datex out request, but this is the default interface (only access to local endpoint) + else this.local_input_handler(data.dxb); } - public static setDatexOut(handler:(dxb:ArrayBuffer, to?:Endpoint, flood?:boolean, source?:any)=>Promise){ + public static setDatexOutHandler(handler:(data: DatexOutData)=>Promise){ + this.datex_out = handler + // TODO: // datex out callback wrapper, handles crypto proxy - this.datex_out = (dxb:ArrayBuffer, to?:Endpoint, flood?:boolean, source?:any) => { - - // redirect as crypto proxy: decrypt - if (to && this.#cryptoProxies.has(to)) { - // TODO#CryptoProxy: decrypt + check channel - const decKey = this.#cryptoProxies.get(to)![1] - console.log("TODO: handle proxy decrypt for " + to) - } - - return handler(dxb, to, flood, source); - } - + // (data: DatexOutData) => { + // // redirect as crypto proxy: decrypt + // // if (to && this.#cryptoProxies.has(to)) { + // // // TODO#CryptoProxy: decrypt + check channel + // // const decKey = this.#cryptoProxies.get(to)![1] + // // console.log("TODO: handle proxy decrypt for " + to) + // // } + + // return handler(data); + // } if (this.#datex_out_handler_initialized_resolve) { this.#datex_out_handler_initialized_resolve(); @@ -964,7 +966,7 @@ export class Runtime { * @param timeout response timeout * @returns evaluated response value */ - public static async datexOut(data:ArrayBuffer|compile_info, to:target_clause=Runtime.endpoint, sid?:number, wait_for_result=true, encrypt=false, detailed_result_callback?:(scope:datex_scope, header:dxb_header, error:Error)=>void, flood = false, flood_exclude?:Endpoint, timeout?:number, source?:Source):Promise{ + public static async datexOut(data:ArrayBuffer|compile_info, to:target_clause=Runtime.endpoint, sid?:number, wait_for_result=true, encrypt=false, detailed_result_callback?:(scope:datex_scope, header:dxb_header, error:Error)=>void, flood = false, flood_exclude?:Endpoint, timeout?:number, socket?:CommunicationInterfaceSocket):Promise{ const finish = this.createPrepocessingTask(); @@ -1003,7 +1005,7 @@ export class Runtime { // single block if (dxb instanceof ArrayBuffer) { - return this.datexOutSingleBlock(dxb, evaluated_receivers, sid, unique_sid, data, wait_for_result, encrypt, detailed_result_callback, flood, flood_exclude, timeout, source); + return this.datexOutSingleBlock(dxb, evaluated_receivers, sid, unique_sid, data, wait_for_result, encrypt, detailed_result_callback, flood, flood_exclude, timeout, socket); } // multiple blocks @@ -1019,9 +1021,9 @@ export class Runtime { // empty arraybuffer indicates that next block is end_of_scope if (next.value.byteLength == 0) end_of_scope = true; // end_of_scope, now return result for last block (wait_for_result) - else if (end_of_scope) return this.datexOutSingleBlock(next.value, evaluated_receivers, sid, unique_sid, data, wait_for_result, encrypt, detailed_result_callback, flood, flood_exclude, timeout, source); + else if (end_of_scope) return this.datexOutSingleBlock(next.value, evaluated_receivers, sid, unique_sid, data, wait_for_result, encrypt, detailed_result_callback, flood, flood_exclude, timeout, socket); // not last block, wait_for_result = false, no detailed_result_callback - else this.datexOutSingleBlock(next.value, evaluated_receivers, sid, unique_sid, data, false, encrypt, null, flood, flood_exclude, timeout, source); + else this.datexOutSingleBlock(next.value, evaluated_receivers, sid, unique_sid, data, false, encrypt, null, flood, flood_exclude, timeout, socket); } } @@ -1040,7 +1042,7 @@ export class Runtime { } // handle sending a single dxb block out - private static datexOutSingleBlock(dxb:ArrayBuffer, to:Disjunction, sid:number, unique_sid:string, data:compile_info, wait_for_result=true, encrypt=false, detailed_result_callback?:(scope:datex_scope, header:dxb_header, error:Error)=>void, flood = false, flood_exclude?:Endpoint, timeout?:number, source?:Source) { + private static datexOutSingleBlock(dxb:ArrayBuffer, to:Disjunction, sid:number, unique_sid:string, data:compile_info, wait_for_result=true, encrypt=false, detailed_result_callback?:(scope:datex_scope, header:dxb_header, error:Error)=>void, flood = false, flood_exclude?:Endpoint, timeout?:number, socket?:CommunicationInterfaceSocket) { // empty filter? if (to?.size == 0) { @@ -1056,28 +1058,37 @@ export class Runtime { // flood exclude flood_exclude receiver if (flood) { - this.datex_out(dxb, flood_exclude, true, source) + this.datex_out({ + dxb, + receivers: BROADCAST, + socket: socket + }) .then(finish) .catch(e => { if (wait_for_result) reject(e); else logger.debug("Error sending datex block (flood)"); }); - } + } // send to receivers else if (to) { //this.datex_out(dxb, to)?.catch(e=>reject(e)); // send and catch errors while sending, like NetworkError - for (const to_endpoint of to) { - // check offline status (async), immediately reject if offline - if (wait_for_result) this._handleEndpointOffline(to_endpoint, reject) - // send dxb - this.datex_out(dxb, to_endpoint, undefined, source) - .then(finish) - .catch(e => { - if (wait_for_result) reject(e); - else logger.debug("Error sending datex block to " + to_endpoint); - }); - } + const isSingleReceiver = to.size == 1; + // check offline status (async), immediately reject if offline + if (isSingleReceiver && wait_for_result) this._handleEndpointOffline([...to][0], reject) + // send dxb + + this.datex_out({ + dxb, + receivers: to, + socket + }) + .then(finish) + .catch(e => { + if (wait_for_result) reject(e); + else logger.debug("Error sending datex block to " + [...to].map(t=>t.toString()).join(", ")); + }); + } // callback for detailed results? @@ -1124,7 +1135,7 @@ export class Runtime { * @param wait_for_result returns the result if set to true * @returns result of the redirected DATEX */ - static async redirectDatex(datex:ArrayBuffer, header:dxb_header, wait_for_result=true, source?:Source):Promise { + static async redirectDatex(datex:ArrayBuffer, header:dxb_header, wait_for_result=true, socket?:CommunicationInterfaceSocket):Promise { // too many redirects (ttl is 0) if (header.routing.ttl == 0) throw new NetworkError(DATEX_ERROR.TOO_MANY_REDIRECTS); @@ -1133,7 +1144,7 @@ export class Runtime { logger.debug("redirect " + (ProtocolDataType[header.type]) + " " + header.sid + " > " + Runtime.valueToDatexString(header.routing.receivers) + ", ttl="+ (header.routing.ttl-1)); - const res = await this.datexOut(datex, header.routing.receivers, header.sid, wait_for_result, undefined, undefined, undefined, undefined, undefined, source); + const res = await this.datexOut(datex, header.routing.receivers, header.sid, wait_for_result, undefined, undefined, undefined, undefined, undefined, socket); return res; } @@ -1176,7 +1187,8 @@ export class Runtime { * Handles beforeunload (sending GOODBYE) * @param endpoint */ - static setActiveEndpoint(endpoint:Endpoint) { + static setActiveEndpoint(endpoint:Endpoint) { + let endpoints:string[] = []; if (client_type == "browser") { try { @@ -1680,7 +1692,10 @@ export class Runtime { public static datexIn(data: DatexInData) { if (data.dxb instanceof ArrayBuffer) return this.handleDatexIn(data.dxb, data.socket.endpoint, undefined, undefined, undefined, data.socket); - else if (data.dxb instanceof ReadableStreamDefaultReader) return this.handleContinuousBlockStream(data.dxb, undefined, undefined, undefined, data.socket.endpoint, data.socket) + else if (data.dxb instanceof ReadableStreamDefaultReader) { + throw new Error("Continuos DATEX block input streams are not supported yet") + // return this.handleContinuousBlockStream(data.dxb, undefined, undefined, undefined, data.socket.endpoint, data.socket) + } else throw new Error("Invalid data for datexIn") } diff --git a/types/addressing.ts b/types/addressing.ts index 627b780e..cd3d10d4 100644 --- a/types/addressing.ts +++ b/types/addressing.ts @@ -339,7 +339,7 @@ export class Endpoint extends Target { title += `${format(Runtime.endpoint)}${ESCAPE_SEQUENCES.RESET} -> ${format(resolvedEndpoint)}${ESCAPE_SEQUENCES.RESET}\n\n` let pre = '' let logs = '' - const rtt = trace.at(-1).timestamp.getTime() - trace.at(0).timestamp.getTime(); + const rtt = trace.at(-1)!.timestamp.getTime() - trace.at(0)!.timestamp.getTime(); pre += `-----------------------------\n` pre += `${ESCAPE_SEQUENCES.BOLD}Round-Trip Time: ${ESCAPE_SEQUENCES.RESET}${rtt}ms\n` From 623cdff6296a61c2e4aa2d96ee081c4416e90ee6 Mon Sep 17 00:00:00 2001 From: benStre Date: Sun, 4 Feb 2024 02:30:34 +0100 Subject: [PATCH 22/60] add interfac implementations --- network/communication-hub.ts | 112 ++++++++++++++---- network/communication-interface.ts | 44 +++++-- .../web-socket-client-interface.ts | 3 - .../window-interface.ts | 43 ++++--- runtime/runtime.ts | 96 ++++++++------- types/addressing.ts | 35 +++--- utils/auto_map.ts | 47 +++++++- utils/global_types.ts | 12 +- 8 files changed, 275 insertions(+), 117 deletions(-) diff --git a/network/communication-hub.ts b/network/communication-hub.ts index 69125258..f84948c6 100644 --- a/network/communication-hub.ts +++ b/network/communication-hub.ts @@ -47,11 +47,20 @@ export class CommunicationHub { return this.handler.removeInterface(comInterface); } - + /** + * Prints the status of all connected interfaces and attached sockets + */ public printStatus() { return this.handler.printStatus(); } + /** + * Lists all available sockets for an endpoint, ordered by relevance + */ + public printEndpointSockets(endpoint: Endpoint) { + return this.handler.printEndpointSockets(endpoint); + } + /** * @private @@ -72,8 +81,12 @@ export class CommunicationHubHandler { #interfaces = new Set() // CommunicationInterfaceSockets are ordered, most recent last - #endpointSockets = new Map>().setAutoDefault(Set) - #registeredSockets = new Map>().setAutoDefault(Set) + #endpointSockets = new Map>().setAutoDefault(Set).enableAutoRemove() + #registeredSockets = new Map>().setAutoDefault(Set).enableAutoRemove() + + // maps main endpoints to a list of instance endpoints that are currently connected via sockets + #activeEndpointInstances = new Map>().setAutoDefault(Set).enableAutoRemove() + #defaultSocket?: ConnectedCommunicationInterfaceSocket #datexInHandler?: DatexInHandler @@ -159,19 +172,34 @@ export class CommunicationHubHandler { } console.log(string) + } + + public printEndpointSockets(endpoint: Endpoint|string) { + endpoint = endpoint instanceof Endpoint ? endpoint : Endpoint.get(endpoint) as Endpoint; + let string = ""; + string += `Available sockets for ${endpoint}:\n` + + for (const socket of this.#endpointSockets.get(endpoint) ?? []) { + string += " - " + socket.toString() + "\n"; + } + + console.log(string) } + /** Internal methods: */ public registerSocket(socket: ConnectedCommunicationInterfaceSocket, endpoint: Endpoint|undefined = socket.endpoint) { + if (this.#endpointSockets.get(endpoint)?.has(socket)) return + if (!endpoint) throw new Error("Cannot register socket to communication hub without endpoint.") - if (this.#endpointSockets.get(endpoint)?.has(socket)) throw new Error("Cannot register socket to communication hub without endpoint.") if (!socket.connected || !socket.endpoint || !socket.interfaceProperties) throw new Error("Cannot register disconnected or uninitialized socket.") this.#logger.debug("Added new" + (socket.endpoint==endpoint?'':' indirect') + " socket " + socket.toString() + " for endpoint " + endpoint.toString()) this.#registeredSockets.getAuto(socket).add(endpoint); this.#endpointSockets.getAuto(endpoint).add(socket); + this.#activeEndpointInstances.getAuto(endpoint.main).add(endpoint); this.sortSockets(endpoint) } @@ -190,29 +218,35 @@ export class CommunicationHubHandler { const endpointSockets = this.#endpointSockets.get(endpoint)!; const socketEndpoints = this.#registeredSockets.get(connectedSocket)!; + const endpointInstances = this.#activeEndpointInstances.getAuto(endpoint.main) // remove own socket endpoint endpointSockets.delete(connectedSocket) socketEndpoints.delete(endpoint) + endpointInstances.delete(endpoint) // direct socket removed, also remove all indirect sockets if (isDirect) { for (const indirectEndpoint of socketEndpoints) { this.#endpointSockets.get(indirectEndpoint)?.delete(connectedSocket) + this.#activeEndpointInstances.get(indirectEndpoint.main)?.delete(indirectEndpoint) } this.#registeredSockets.delete(connectedSocket) } - - if (endpointSockets.size == 0) this.#endpointSockets.delete(endpoint) - if (socketEndpoints.size == 0) this.#registeredSockets.delete(connectedSocket) } + public setDatexInHandler(handler: DatexInHandler) { this.#datexInHandler = handler } - public hasSocket(socket: CommunicationInterfaceSocket) { - return this.#registeredSockets.has(socket as ConnectedCommunicationInterfaceSocket) + /** + * Returns true when the socket is registered. + * Returns true when the endpoint is registered for the socket (if an endpoint is provided). + */ + public hasSocket(socket: CommunicationInterfaceSocket, endpoint?: Endpoint) { + if (endpoint) return this.#registeredSockets.get(socket as ConnectedCommunicationInterfaceSocket)?.has(endpoint) + else return this.#registeredSockets.has(socket as ConnectedCommunicationInterfaceSocket) } /** @@ -226,39 +260,67 @@ export class CommunicationHubHandler { } /** - * Sort available sockets for endpoint by priority and connectTimestamp - * @param endpoint + * Sort available sockets for endpoint: + * - direct sockets first + * - then sort by priority + * - then sort by connectTimestamp */ private sortSockets(endpoint: Endpoint) { const sockets = this.#endpointSockets.get(endpoint) if (!sockets) throw new Error("No sockets for endpoint " + endpoint); const sortedSockets = new Set( - Object - // group by priority - .entries(Object.groupBy(sockets, socket => socket.interfaceProperties.priority)) - // sort by priority - .sort(([a], [b]) => Number(b) - Number(a)) - // sort by connectTimestamp in each priority group - .map(([priority, sockets]) => [priority, sockets!.toSorted( - (a, b) => b.connectTimestamp - a.connectTimestamp - )] as const) - // flatten - .flatMap(([_, sockets]) => sockets) + Object + // group by direct/indirect + .entries(Object.groupBy(sockets, socket => (socket.endpoint!==endpoint).toString())) + // sort by direct/indirect + .toSorted() + + // sort by priority and timestamp, flatten + .flatMap(([_, sockets]) => this.sortSocketsByPriorityAndTimestamp(sockets!)) ) this.#endpointSockets.set(endpoint, sortedSockets) } + private sortSocketsByPriorityAndTimestamp(sockets: Iterable) { + return Object + // group by priority + .entries(Object.groupBy(sockets, socket => socket.interfaceProperties.priority)) + // sort by priority + .toSorted(([a], [b]) => Number(b) - Number(a)) + // sort by connectTimestamp in each priority group + .map(([priority, sockets]) => [priority, sockets!.toSorted( + (a, b) => b.connectTimestamp - a.connectTimestamp + )] as const) + // flatten + .flatMap(([_, sockets]) => sockets) + } + + private getPreferredSocketForEndpoint(endpoint: Endpoint, excludeSocket?: CommunicationInterfaceSocket) { - for (const socket of this.#endpointSockets.get(endpoint) ?? []) { - if (socket === excludeSocket) continue; - return socket; + // find socket that matches endpoint instance exactly + const socket = this.findMatchingEndpointSocket(endpoint, excludeSocket); + if (socket) return socket; + + // find socket that matches instance if main endpoint + if (endpoint.main === endpoint) { + const instances = [...this.#activeEndpointInstances.get(endpoint)??[]]; + for (let i=instances.length-1; i>=0; i--) { + const socket = this.findMatchingEndpointSocket(instances[i], excludeSocket); + if (socket) return socket; + } } if (this.#defaultSocket !== excludeSocket) return this.#defaultSocket; } + private findMatchingEndpointSocket(endpoint: Endpoint, excludeSocket?: CommunicationInterfaceSocket) { + for (const socket of this.#endpointSockets.get(endpoint) ?? []) { + if (socket === excludeSocket) continue; + return socket; + } + } /** diff --git a/network/communication-interface.ts b/network/communication-interface.ts index 2b9eca4b..958b60e7 100644 --- a/network/communication-interface.ts +++ b/network/communication-interface.ts @@ -1,6 +1,8 @@ import { ProtocolDataType } from "../compiler/protocol_types.ts"; -import { LOCAL_ENDPOINT, Runtime } from "../datex_all.ts"; +import { LOCAL_ENDPOINT, Runtime, dxb_header } from "../datex_all.ts"; +import { Crypto } from "../runtime/crypto.ts"; import { Endpoint } from "../types/addressing.ts"; +import { Compiler } from "../compiler/compiler.ts"; import { Logger } from "../utils/logger.ts"; import { COM_HUB_SECRET, communicationHub } from "./communication-hub.ts"; @@ -40,6 +42,10 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { #destroyed = false; #opened = false; + + static defaultLogger = new Logger("CommunicationInterfaceSocket") + public logger = CommunicationInterfaceSocket.defaultLogger; + #connectTimestamp = Date.now() get connectTimestamp() { @@ -121,10 +127,17 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { if (this.#destroyed) throw new Error("Cannot receive on destroyed socket"); if (!this.connected) throw new Error("Cannot receive on disconnected socket"); - const header = await communicationHub.handler.datexIn({ - dxb, - socket: this - }) + let header: dxb_header; + try { + header = await communicationHub.handler.datexIn({ + dxb, + socket: this + }) + } + catch (e) { + console.error(e); + return; + } // listen for GOODBYE messages if (this.endpoint) { @@ -134,8 +147,11 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { this.dispatchEvent(new CustomEvent('endpoint-disconnect')) } // message from another endpoint, record as indirect socket connection - else if (header.sender !== this.endpoint) { - communicationHub.handler.registerSocket(this as ConnectedCommunicationInterfaceSocket, header.sender) + else if (header.sender !== this.endpoint && !communicationHub.handler.hasSocket(this as ConnectedCommunicationInterfaceSocket, header.sender)) { + if (header.sender === Runtime.endpoint) { + this.logger.error("Indirect connection to own endpoint detected at "+this) + } + else communicationHub.handler.registerSocket(this as ConnectedCommunicationInterfaceSocket, header.sender) } } // detect new endpoint @@ -233,6 +249,7 @@ export abstract class CommunicationInterface { // remove old socket @@ -241,7 +258,18 @@ export abstract class CommunicationInterface { - console.log("receive ws client") this.receive(event.data) } open() { - console.log("open ws client") this.webSocket.addEventListener('message', this.handleReceive); } close() { - console.log("close ws client") this.webSocket.removeEventListener('message', this.handleReceive); } diff --git a/network/communication-interfaces/window-interface.ts b/network/communication-interfaces/window-interface.ts index b7c92d30..5fbec8ea 100644 --- a/network/communication-interfaces/window-interface.ts +++ b/network/communication-interfaces/window-interface.ts @@ -1,7 +1,7 @@ import { Runtime } from "../../runtime/runtime.ts"; import { Endpoint, Target } from "../../types/addressing.ts"; import { CommunicationInterface, CommunicationInterfaceSocket, InterfaceDirection, InterfaceProperties } from "../communication-interface.ts"; - +import { communicationHub } from "../communication-hub.ts"; export class WindowInterfaceSocket extends CommunicationInterfaceSocket { constructor(public readonly window: Window, public readonly windowOrigin: string) { @@ -9,19 +9,16 @@ export class WindowInterfaceSocket extends CommunicationInterfaceSocket { } handleReceive = (event: MessageEvent) => { - console.log("receive window client") if (event.origin == this.windowOrigin && event.data instanceof ArrayBuffer) { this.receive(event.data) } } open() { - console.log("open window client") globalThis.addEventListener('message', this.handleReceive); } close() { - console.log("close window client") globalThis.removeEventListener('message', this.handleReceive); } @@ -97,6 +94,7 @@ export class WindowInterface extends CommunicationInterface { // if in sub window: send INIT to parent immediately this.sendInit(); } + this.handleClose(); } connect() { @@ -116,17 +114,30 @@ export class WindowInterface extends CommunicationInterface { }, this.#windowOrigin); } + onClose?: ()=>void + + private handleClose() { + const interval = setInterval(() => { + if (this.#window.closed) { + clearInterval(interval); + console.log("closed") + this.clearSockets() + this.onClose?.() + } + }, 1000); + } + private onReceive = (event: MessageEvent) => { if (event.origin == this.#windowOrigin) { const data = event.data; - // receive as parent if (data?.type == "INIT") { globalThis.removeEventListener("message", this.onReceive); const socket = new WindowInterfaceSocket(this.#window, this.#windowOrigin) socket.endpoint = Target.get(data.endpoint) as Endpoint; this.addSocket(socket) + // if in parent: send INIT to window after initialized if (!this.#isChild) this.sendInit(); } @@ -147,20 +158,20 @@ export class WindowInterface extends CommunicationInterface { } /** - * Open a new window and attaches a WindowInterface - * The interface must still be added to the communication hub with `communicationHub.addInterface(window.interface)` + * Opens a new window and registers a attached WindowInterface. + * The WindowInterface is automatically removed when the window is closed. */ - static openWindow(url: string | URL, target?: string, features?: string) { + static createWindow(url: string | URL, target?: string, features?: string) { const newWindow = window.open(url, target, features); - if (!newWindow) return { - window: null, - windowInterface: null - }; + if (!newWindow) return null; const windowInterface = this.createChildInterface(newWindow, url) - return { - window: newWindow, - windowInterface - }; + + communicationHub.addInterface(windowInterface) + windowInterface.onClose = () => { + communicationHub.removeInterface(windowInterface) + } + + return newWindow } } \ No newline at end of file diff --git a/runtime/runtime.ts b/runtime/runtime.ts index c1c384f3..9f1abe2e 100644 --- a/runtime/runtime.ts +++ b/runtime/runtime.ts @@ -35,7 +35,7 @@ import { Function as DatexFunction } from "../types/function.ts"; import { Storage } from "../runtime/storage.ts"; import { Observers } from "../utils/observers.ts"; import { BinaryCode } from "../compiler/binary_codes.ts"; -import type { ExecConditions, compile_info, datex_meta, datex_scope, dxb_header, routing_info } from "../utils/global_types.ts"; +import type { ExecConditions, trace, compile_info, datex_meta, datex_scope, dxb_header, routing_info } from "../utils/global_types.ts"; import { Markdown } from "../types/markdown.ts"; import { Type } from "../types/type.ts"; import { Tuple } from "../types/tuple.ts"; @@ -893,7 +893,9 @@ export class Runtime { * @returns compiled DATEX Binary */ protected static async compileAdvanced(data:compile_info):Promise { - let header_options = data[2]; + const header_options = data[2]; + + if (!header_options) throw new Error("header_options not defined") // get sid or generate new if (header_options.sid == null) header_options.sid = Compiler.generateSID(); @@ -1216,7 +1218,6 @@ export class Runtime { else { endpoints.push(endpoint.toString()) this.ownLastEndpoint = endpoint; - this.lastEndpointUnloadHandler = () => { // send goodbye if (this.goodbyeMessage) sendDatexViaHTTPChannel(this.goodbyeMessage); @@ -1630,41 +1631,42 @@ export class Runtime { if ((!res[0].redirect && !force_only_header_info) || force_no_redirect) { [header, data_buffer, header_buffer, signature_start, iv, encrypted_key] = res; - // save encrypted key? - if (encrypted_key) { - const sym_enc_key = await Crypto.extractEncryptedKey(encrypted_key); - await this.setScopeSymmetricKeyForSender(header.sid, header.sender, sym_enc_key) - } - - // get signature - if (header.signed) { - if (!header.sender) throw [header, new SecurityError("Signed DATEX without a sender")]; - let j = signature_start; - const signature = header_buffer.subarray(j, j + Compiler.signature_size); - const content = new Uint8Array(dxb).subarray(j + Compiler.signature_size); - j += Compiler.signature_size; - const valid = await Crypto.verify(content, signature, header.sender); + try { + // save encrypted key? + if (encrypted_key) { + const sym_enc_key = await Crypto.extractEncryptedKey(encrypted_key); + await this.setScopeSymmetricKeyForSender(header.sid, header.sender, sym_enc_key) + } - if (!valid) { - logger.error("Invalid signature from " + header.sender); - throw [header, new SecurityError("Invalid signature from " + header.sender)]; + // get signature + if (header.signed) { + if (!header.sender) throw new SecurityError("Signed DATEX without a sender"); + let j = signature_start; + const signature = header_buffer.subarray(j, j + Compiler.signature_size); + const content = new Uint8Array(dxb).subarray(j + Compiler.signature_size); + j += Compiler.signature_size; + const valid = await Crypto.verify(content, signature, header.sender); + + if (!valid) { + logger.error("Invalid signature from " + header.sender); + throw new SecurityError("Invalid signature from " + header.sender); + } } - } - // decrypt + // decrypt - if (header.encrypted) { - if (!iv) throw [header, new SecurityError("DATEX not correctly encrypted")]; - // try to decrypt body - try { + if (header.encrypted) { + if (!iv) throw new SecurityError("DATEX not correctly encrypted"); + // try to decrypt body data_buffer = new Uint8Array(await Crypto.decryptSymmetric(data_buffer.buffer, force_sym_enc_key ?? await this.getScopeSymmetricKeyForSender(header.sid, header.sender), iv)); - } catch(e) { - throw [header, e]; } + + // header data , body buffer, header buffer, original (encrypted) body buffer + return [header, data_buffer, header_buffer, res[1]]; + } + catch (e) { + throw [header, e]; } - - // header data , body buffer, header buffer, original (encrypted) body buffer - return [header, data_buffer, header_buffer, res[1]]; } @@ -1701,7 +1703,7 @@ export class Runtime { // extract dxb blocks from a continuos stream - private static async handleContinuousBlockStream(dxb_stream_reader: ReadableStreamDefaultReader, full_scope_callback, variables?:any, header_callback?:(header:dxb_header)=>void, last_endpoint?:Endpoint, source?:Source) { + private static async handleContinuousBlockStream(dxb_stream_reader: ReadableStreamDefaultReader, full_scope_callback, variables?:any, header_callback?:(header:dxb_header)=>void, last_endpoint?:Endpoint, socket?:CommunicationInterfaceSocket) { let current_block: Uint8Array; let current_block_size: number @@ -1769,7 +1771,8 @@ export class Runtime { // block end if (current_block && index >= current_block_size) { console.log("received new block from stream") - this.handleDatexIn(current_block.buffer, last_endpoint, full_scope_callback, variables, header_callback, source); + this.handleDatexIn(current_block.buffer, last_endpoint, full_scope_callback, variables, header_callback, socket) + .catch(e=>console.error("Error handling block stream: ", e)) // reset for next block current_block = null; index = 0; // force to 0 @@ -1871,7 +1874,7 @@ export class Runtime { * @param header_callback callback method returning information for the evaluated header before executing the dxb * @returns header information (after executing the dxb) */ - private static async handleDatexIn(dxb:ArrayBuffer, last_endpoint?:Endpoint, full_scope_callback?:(sid:number, scope:any, error?:boolean)=>void, _?:any, header_callback?:(header:dxb_header)=>void, source?: CommunicationInterfaceSocket): Promise { + private static async handleDatexIn(dxb:ArrayBuffer, last_endpoint?:Endpoint, full_scope_callback?:(sid:number, scope:any, error?:boolean)=>void, _?:any, header_callback?:(header:dxb_header)=>void, socket?: CommunicationInterfaceSocket): Promise { let header:dxb_header, data_uint8:Uint8Array; @@ -1882,13 +1885,15 @@ export class Runtime { catch (e) { // e is [dxb_header, Error] //throw e - console.error(e[1]??e) const header = e[0]; if (header) { this.handleScopeError(header, e[1]); this.updateEndpointOnlineState(header); + console.error(e[1]??e) + + return header; } - return; + throw e; } @@ -1945,7 +1950,7 @@ export class Runtime { } } try { - await to.trace({header: res, source, trace}) + await to.trace({header: res, socket, trace}) } catch {} return {}; @@ -1955,7 +1960,7 @@ export class Runtime { } } - await this.redirectDatex(dxb, res, false, source); + await this.redirectDatex(dxb, res, false, socket); } catch (e) { console.log("redirect failed", e) @@ -1963,10 +1968,10 @@ export class Runtime { // callback for header info if (header_callback instanceof globalThis.Function) header_callback(res); - return; + return res; } - let data = data_uint8.buffer; // get array buffer + const data = data_uint8.buffer; // get array buffer // create map for this sender if (!this.active_datex_scopes.has(header.sender)) { @@ -1989,7 +1994,7 @@ export class Runtime { // get existing scope or create new let scope = scope_map?.scope ?? this.createNewInitialScope(header); - scope.source = source; + scope.socket = socket; // those values can change later in the while loop let _header = header; @@ -2166,7 +2171,8 @@ export class Runtime { { if (header.type == ProtocolDataType.TRACE_BACK) { - return_value.push({endpoint:Runtime.endpoint, interface: {type: scope.source?.type, description: scope.source?.description}, timestamp: new Date()}); + const traceStack = return_value as trace[] + traceStack.push({endpoint:Runtime.endpoint, socket: {type: scope.socket?.interfaceProperties?.type??"unknown", name: scope.socket?.interfaceProperties?.name}, timestamp: new Date()}); } // handle result @@ -2215,11 +2221,11 @@ export class Runtime { else if (header.type == ProtocolDataType.TRACE) { const sender = return_value[0].endpoint; - - return_value.push({endpoint:Runtime.endpoint, destReached:true, interface: {type: scope.source?.type, description: scope.source?.description}, timestamp: new Date()}); + const traceStack = return_value as trace[]; + traceStack.push({endpoint:Runtime.endpoint, destReached:true, socket: {type: scope.socket?.interfaceProperties?.type??"unknown", name: scope.socket?.interfaceProperties?.name}, timestamp: new Date()}); console.log("TRACE request from " + sender); - this.datexOut(["?", [return_value], {type:ProtocolDataType.TRACE_BACK, to:sender, return_index:header.return_index, encrypt:header.encrypted, sign:header.signed}], sender, header.sid, false); + this.datexOut(["?", [traceStack], {type:ProtocolDataType.TRACE_BACK, to:sender, return_index:header.return_index, encrypt:header.encrypted, sign:header.signed}], sender, header.sid, false); } else if (header.type == ProtocolDataType.DEBUGGER) { diff --git a/types/addressing.ts b/types/addressing.ts index cd3d10d4..6d94b42c 100644 --- a/types/addressing.ts +++ b/types/addressing.ts @@ -3,7 +3,7 @@ import { Pointer } from "../runtime/pointers.ts"; import { ValueConsumer } from "./abstract_types.ts"; import { ValueError } from "./errors.ts"; import { Compiler, ProtocolDataTypesMap } from "../compiler/compiler.ts"; -import type { datex_scope, dxb_header } from "../utils/global_types.ts"; +import type { datex_scope, dxb_header, trace } from "../utils/global_types.ts"; import { base64ToArrayBuffer, buffer2hex, hex2buffer } from "../utils/utils.ts"; import { clause, Disjunction } from "./logic.ts"; import { Runtime, StaticScope } from "../runtime/runtime.ts"; @@ -13,6 +13,7 @@ import { ProtocolDataType } from "../compiler/protocol_types.ts"; import { ESCAPE_SEQUENCES } from "../utils/logger.ts"; import { deleteCookie, getCookie } from "../utils/cookies.ts"; import { Crypto } from "../runtime/crypto.ts"; +import { CommunicationInterfaceSocket } from "../network/communication-interface.ts"; type target_prefix_person = "@"; type target_prefix_id = "@@"; @@ -301,23 +302,24 @@ export class Endpoint extends Target { * Generates a network trace * (for routing debugging) */ - public async trace(previous?: {header: dxb_header, trace: any[], source?: any}):Promise<{endpoint: Endpoint, timestamp: Date, interface: {type?: string, description?:string}}[]> { + public async trace(previous?: {header: dxb_header, trace: trace[], socket?: CommunicationInterfaceSocket}):Promise { if (previous) { console.log(ProtocolDataTypesMap[previous.header.type??ProtocolDataType.TRACE]+" from " + previous.header.sender + " to " + this); } const trace = previous?.trace ?? []; - trace.push({endpoint:Runtime.endpoint, interface: {type: previous?.source?.type, description: previous?.source?.description}, timestamp: new Date()}); + const properties = previous?.socket?.interfaceProperties; + trace.push({endpoint:Runtime.endpoint, socket: {type: properties?.type??"unknown", name: properties?.name}, timestamp: new Date()}); - const res = await Runtime.datexOut(['?', [trace], {type:previous?.header?.type ?? ProtocolDataType.TRACE, sign:false}], this, previous?.header?.sid, true, false, undefined, false, undefined, 60_000, previous?.source); + const res = await Runtime.datexOut(['?', [trace], {type:previous?.header?.type ?? ProtocolDataType.TRACE, sign:false}], this, previous?.header?.sid, true, false, undefined, false, undefined, 60_000, previous?.socket); return res; } public async printTrace() { const format = (val:any) => Runtime.valueToDatexStringExperimental(val, true, true); - let trace: {endpoint: Endpoint, timestamp: Date, interface: {type?: string, description?:string}}[] + let traceStack: trace[] try { - trace = await this.trace(); + traceStack = await this.trace(); } catch { let title = `${ESCAPE_SEQUENCES.BOLD}DATEX Network Trace\n${ESCAPE_SEQUENCES.RESET}`; @@ -327,19 +329,18 @@ export class Endpoint extends Target { return; } - if (!trace) throw new Error("Invalid trace"); + if (!traceStack) throw new Error("Invalid trace"); - const resolvedEndpointData = trace.find((data) => trace.indexOf(data)!=0 && (data.endpoint == this || data.endpoint.main == this || (data.endpoint == Runtime.endpoint && (this as any)==Datex.LOCAL_ENDPOINT)))!; - const resolveEndpointIndex = trace.indexOf(resolvedEndpointData); + const resolvedEndpointData = traceStack.find((data) => traceStack.indexOf(data)!=0 && (data.endpoint == this || data.endpoint.main == this || (data.endpoint == Runtime.endpoint && (this as any)==Datex.LOCAL_ENDPOINT)))!; + const resolveEndpointIndex = traceStack.indexOf(resolvedEndpointData); const resolvedEndpoint = resolvedEndpointData.endpoint; const hopsToDest = resolveEndpointIndex; - const hopsFromDest = trace.length - resolveEndpointIndex - 1; + const hopsFromDest = traceStack.length - resolveEndpointIndex - 1; let title = `${ESCAPE_SEQUENCES.BOLD}DATEX Network Trace\n${ESCAPE_SEQUENCES.RESET}`; title += `${format(Runtime.endpoint)}${ESCAPE_SEQUENCES.RESET} -> ${format(resolvedEndpoint)}${ESCAPE_SEQUENCES.RESET}\n\n` let pre = '' - let logs = '' - const rtt = trace.at(-1)!.timestamp.getTime() - trace.at(0)!.timestamp.getTime(); + const rtt = traceStack.at(-1)!.timestamp.getTime() - traceStack.at(0)!.timestamp.getTime(); pre += `-----------------------------\n` pre += `${ESCAPE_SEQUENCES.BOLD}Round-Trip Time: ${ESCAPE_SEQUENCES.RESET}${rtt}ms\n` @@ -349,18 +350,18 @@ export class Endpoint extends Target { pre += `\n${ESCAPE_SEQUENCES.BOLD}Hops:${ESCAPE_SEQUENCES.RESET}\n\n`; - for (let i = 0; i ${format(next.endpoint)}${ESCAPE_SEQUENCES.RESET}\n\n` + pre += `${ESCAPE_SEQUENCES.BOLD} #${(i%hopsToDest)+1} ${ESCAPE_SEQUENCES.RESET}(${next.socket.type}${next.socket.name ? ' ' + next.socket.name : ''})${ESCAPE_SEQUENCES.RESET}:\n ${format(current.endpoint)}${ESCAPE_SEQUENCES.RESET} -> ${format(next.endpoint)}${ESCAPE_SEQUENCES.RESET}\n\n` } - console.log(title+pre+logs) + console.log(title+pre) } diff --git a/utils/auto_map.ts b/utils/auto_map.ts index 80b0d213..8b02dee9 100644 --- a/utils/auto_map.ts +++ b/utils/auto_map.ts @@ -1,7 +1,7 @@ // extends Map class to automatically create new empty entries when the getAuto() method is called and the entry does not exist -import type { any_class } from "unyt_core/utils/global_types.ts"; +import type { any_class } from "./global_types.ts"; const DEFAULT_CLASS = Symbol('DEFAULT_CLASS') const DEFAULT_IS_CLASS = Symbol('DEFAULT_IS_CLASS') @@ -11,7 +11,10 @@ const DEFAULT_VALUE = Symbol('DEFAULT_VALUE') export const _ = "_"; -export type AutoMap = Map & {getAuto(key: K): V} +export type AutoMap = Map & { + getAuto(key: K): V; + enableAutoRemove(): AutoRemoveMap & AutoMap +} // TODO declare global { @@ -37,6 +40,46 @@ Map.prototype.setAutoDefault = function(default_class_or_creator_function_or_ return this; } + +class AutoRemoveMap extends Map { + constructor(entries?: readonly (readonly [K, V])[] | null) { + super(entries); + for (const [key, value] of this) { + this.#enableAutoRemove(key, value); + } + } + + set(key: K, value: V) { + this.#enableAutoRemove(key, value); + return super.set(key, value); + } + + #enableAutoRemove(mapKey: K, value: V) { + if (value instanceof Set) { + const originalDelete = value.delete.bind(value); + value.delete = (key: K) => { + const res = originalDelete(key); + if (value.size == 0) this.delete(mapKey); + return res; + } + } + // TODO: more types + } +} + +Map.prototype.enableAutoRemove = function() { + const map = new AutoRemoveMap([...this.entries()]); + + if ((this as any)[DEFAULT_CLASS]) (map as any)[DEFAULT_CLASS] = (this as any)[DEFAULT_CLASS] + if ((this as any)[DEFAULT_IS_CLASS]) (map as any)[DEFAULT_IS_CLASS] = (this as any)[DEFAULT_IS_CLASS] + if ((this as any)[DEFAULT_CLASS_PRIMITIVE]) (map as any)[DEFAULT_CLASS_PRIMITIVE] = (this as any)[DEFAULT_CLASS_PRIMITIVE] + if ((this as any)[DEFAULT_CREATOR_FUNCTION]) (map as any)[DEFAULT_CREATOR_FUNCTION] = (this as any)[DEFAULT_CREATOR_FUNCTION] + if ((this as any)[DEFAULT_VALUE]) (map as any)[DEFAULT_VALUE] = (this as any)[DEFAULT_VALUE] + + return map; +} + + Map.prototype.getAuto = function(key: K): V { if (!this.has(key)) this.set(key, this[DEFAULT_CREATOR_FUNCTION] ? diff --git a/utils/global_types.ts b/utils/global_types.ts index 8c547547..045649b7 100644 --- a/utils/global_types.ts +++ b/utils/global_types.ts @@ -7,6 +7,7 @@ import { Endpoint, Target, target_clause } from "../types/addressing.ts" import { compiler_options, PrecompiledDXB, DatexResponse } from "../compiler/compiler.ts" import { cnf, Connective, Disjunction } from "../types/logic.ts" import { NOT_EXISTING } from "../runtime/constants.ts"; +import { CommunicationInterfaceSocket } from "../network/communication-interface.ts"; // return type for remote function calls @@ -144,6 +145,15 @@ export type datex_variables_scope = { [key: string]: any } & { // all available export type datex_meta = {encrypted?:boolean, signed?:boolean, sender:Endpoint, timestamp:Date, type:ProtocolDataType, local?:boolean}; +export type trace = { + endpoint: Endpoint, + timestamp: Date, + destReached?: boolean, + socket: { + type: string, + name?:string + } +} export type datex_scope = { sid: number, @@ -151,7 +161,7 @@ export type datex_scope = { sender: Endpoint, // sender of the scope origin: Endpoint, // origin to use for pointers / casting (default is sender) - source?: any // original source (com interface) from which this scope was received + socket?: CommunicationInterfaceSocket // original socket (com interface) from which this scope was received current_index: number, start_index: number, // keep track of index to jump back to From bc45f7e5a3045c649889af208a75b6b0d24cdf14 Mon Sep 17 00:00:00 2001 From: benStre Date: Sun, 4 Feb 2024 21:36:03 +0100 Subject: [PATCH 23/60] handle HELLO, GOODBYE, migrate Datex.Supranet --- init.ts | 2 + network/communication-hub.ts | 200 ++++++++++++++++-- network/communication-interface.ts | 149 ++++++++++--- .../local-loopback-interface.ts | 9 +- .../web-socket-client-interface.ts | 3 + .../window-interface.ts | 19 +- network/supranet.ts | 146 +++++-------- network/unyt.ts | 16 +- runtime/endpoint_config.ts | 2 +- runtime/runtime.ts | 11 +- types/addressing.ts | 26 ++- 11 files changed, 417 insertions(+), 166 deletions(-) diff --git a/init.ts b/init.ts index 16210a38..40918bd2 100644 --- a/init.ts +++ b/init.ts @@ -24,10 +24,12 @@ export async function init() { registerStorageAsPointerSource(); // bind communication hub handlers to runtime + communicationHub.handler.init() communicationHub.handler.setDatexInHandler(Runtime.datexIn.bind(Runtime)) Runtime.setDatexOutHandler(communicationHub.handler.datexOut.bind(communicationHub.handler)) await communicationHub.addInterface(new LocalLoopbackInterface()) + // @ts-ignore NO_INIT if (!globalThis.NO_INIT) { diff --git a/network/communication-hub.ts b/network/communication-hub.ts index f84948c6..dbc9aa27 100644 --- a/network/communication-hub.ts +++ b/network/communication-hub.ts @@ -1,5 +1,5 @@ import { dxb_header } from "../utils/global_types.ts"; -import { Endpoint } from "../types/addressing.ts"; +import { Endpoint, LOCAL_ENDPOINT } from "../types/addressing.ts"; import { CommunicationInterface, CommunicationInterfaceSocket, ConnectedCommunicationInterfaceSocket } from "./communication-interface.ts"; import { Disjunction } from "../types/logic.ts"; import "../utils/auto_map.ts"; @@ -8,6 +8,9 @@ import { ESCAPE_SEQUENCES, Logger } from "../utils/logger.ts"; import { Datex } from "../mod.ts"; import { NetworkError } from "../types/errors.ts"; import { Compiler } from "../compiler/compiler.ts"; +import { Runtime } from "../runtime/runtime.ts"; +import { ProtocolDataType } from "../compiler/protocol_types.ts"; +import { Crypto } from "../runtime/crypto.ts"; export type DatexInData = { dxb: ArrayBuffer|ReadableStreamDefaultReader, @@ -39,6 +42,10 @@ export class CommunicationHub { return this.#instance; } + get defaultSocket() { + return this.handler.defaultSocket; + } + public addInterface(comInterface: CommunicationInterface, setAsDefault = false) { return this.handler.addInterface(comInterface, setAsDefault); } @@ -77,6 +84,12 @@ export const COM_HUB_SECRET = Symbol("COM_HUB_SECRET") */ export class CommunicationHubHandler { + /** + * Interval for checking online status for indirect/direct socket endpoints + */ + readonly CLEANUP_INTERVAL = 10 * 60 * 1000; // 10min + + #logger = new Logger("CommunicationHub") #interfaces = new Set() @@ -87,8 +100,17 @@ export class CommunicationHubHandler { // maps main endpoints to a list of instance endpoints that are currently connected via sockets #activeEndpointInstances = new Map>().setAutoDefault(Set).enableAutoRemove() + #defaultInterface?: CommunicationInterface #defaultSocket?: ConnectedCommunicationInterfaceSocket + set defaultSocket(socket: ConnectedCommunicationInterfaceSocket|undefined) { + this.#defaultSocket = socket; + if (this.#defaultSocket) Runtime.setMainNode(this.#defaultSocket.endpoint); + } + get defaultSocket() { + return this.#defaultSocket; + } + #datexInHandler?: DatexInHandler directionSymbols = { @@ -97,12 +119,16 @@ export class CommunicationHubHandler { [InterfaceDirection.IN_OUT]: "◀─▶" } + constructor() { + this.startCleanupInterval() + } /** Public facing methods: **/ + public async addInterface(comInterface: CommunicationInterface, setAsDefault = false) { this.#interfaces.add(comInterface) await comInterface.init(COM_HUB_SECRET); - if (setAsDefault) this.#defaultSocket = comInterface.getSockets().values().next().value + if (setAsDefault) this.setDefaultInterface(comInterface) } public async removeInterface(comInterface: CommunicationInterface) { @@ -150,7 +176,7 @@ export class CommunicationHubHandler { } } - string += "Default socket: " + (this.#defaultSocket ? this.#defaultSocket.toString() : "none") + "\n"; + string += "Default socket: " + (this.defaultSocket ? this.defaultSocket.toString() : "none") + "\n"; // print @@ -167,7 +193,7 @@ export class CommunicationHubHandler { ) : ESCAPE_SEQUENCES.UNYT_RED const connectedState = `${color}⬤${ESCAPE_SEQUENCES.RESET}` - string += ` ${connectedState} ${directionSymbol}${isDirect?'':' (indirect)'} ${endpoint??'unknown endpoint'}\n` + string += ` ${connectedState} ${directionSymbol}${isDirect?'':' (indirect)'}${isDirect&&this.defaultSocket==socket?' (default)':''} ${endpoint??'unknown endpoint'}\n` } } @@ -180,7 +206,7 @@ export class CommunicationHubHandler { let string = ""; string += `Available sockets for ${endpoint}:\n` - for (const socket of this.#endpointSockets.get(endpoint) ?? []) { + for (const socket of this.iterateEndpointSockets(endpoint, false, false)) { string += " - " + socket.toString() + "\n"; } @@ -191,15 +217,25 @@ export class CommunicationHubHandler { /** Internal methods: */ public registerSocket(socket: ConnectedCommunicationInterfaceSocket, endpoint: Endpoint|undefined = socket.endpoint) { - if (this.#endpointSockets.get(endpoint)?.has(socket)) return + if (this.#endpointSockets.get(endpoint)?.has(socket)) return; if (!endpoint) throw new Error("Cannot register socket to communication hub without endpoint.") if (!socket.connected || !socket.endpoint || !socket.interfaceProperties) throw new Error("Cannot register disconnected or uninitialized socket.") - this.#logger.debug("Added new" + (socket.endpoint==endpoint?'':' indirect') + " socket " + socket.toString() + " for endpoint " + endpoint.toString()) + const isDirect = socket.endpoint==endpoint; + + // set default socket + if (isDirect && socket.toString()==this.#defaultInterface?.toString() && socket.canSend) { + this.#logger.debug("Setting default socket " + socket.toString() + " (endpoint " + endpoint.toString()+")") + this.defaultSocket = socket; + } + + + this.#logger.debug("Added new" + (isDirect?'':' indirect') + " socket " + socket.toString() + " for endpoint " + endpoint.toString()) this.#registeredSockets.getAuto(socket).add(endpoint); this.#endpointSockets.getAuto(endpoint).add(socket); - this.#activeEndpointInstances.getAuto(endpoint.main).add(endpoint); + // add to instances map if not main endpoint + if (endpoint.main !== endpoint) this.#activeEndpointInstances.getAuto(endpoint.main).add(endpoint); this.sortSockets(endpoint) } @@ -209,11 +245,13 @@ export class CommunicationHubHandler { if (!this.#endpointSockets.has(endpoint)) throw new Error("Cannot unregister socket, not registered for endpoint.") if (!this.#registeredSockets.has(connectedSocket)) throw new Error("Cannot unregister socket, not registered.") - // remove default socket - if (connectedSocket === this.#defaultSocket) this.#defaultSocket = undefined; - const isDirect = connectedSocket.endpoint==endpoint; + // remove default socket + if (isDirect && connectedSocket === this.defaultSocket) { + this.defaultSocket = undefined + } + this.#logger.debug("Removed" + (isDirect?'':' indirect') + " socket " + connectedSocket.toString() + " for endpoint " + endpoint.toString()) const endpointSockets = this.#endpointSockets.get(endpoint)!; @@ -240,6 +278,66 @@ export class CommunicationHubHandler { this.#datexInHandler = handler } + + private startCleanupInterval() { + setInterval(() => { + for (const endpoint of this.#endpointSockets.keys()) { + endpoint.isOnline(); + } + }, this.CLEANUP_INTERVAL) + } + + /** + * @private + */ + async init() { + let lastEndpointGooodbyeMessage = await this.compileGoodbyeMessage(); + Runtime.onEndpointChanged(async (endpoint) => { + this.#logger.debug("Endpoint changed to " + endpoint.toString()) + + // send GOODBYE for previous endpoint + if (lastEndpointGooodbyeMessage) { + this.#logger.debug("Broadcasting GOODBYE for previous endpoint over all sockets"); + + // iterate direct outgoing sockets + for (const socket of this.iterateSockets()) { + console.log("send", socket, lastEndpointGooodbyeMessage) + socket.sendGoodbye(lastEndpointGooodbyeMessage) + } + } + + await sleep(1000); + + // iterate direct outgoing sockets + const helloMessage = await this.compileHelloMessage(1); + if (helloMessage) { + for (const socket of this.iterateSockets()) { + socket.sendHello(helloMessage) + } + } + + + lastEndpointGooodbyeMessage = await this.compileGoodbyeMessage(); + }) + } + + public compileGoodbyeMessage() { + if (!Runtime.endpoint || Runtime.endpoint == LOCAL_ENDPOINT) return; + return Compiler.compile("", [], {type:ProtocolDataType.GOODBYE, sign:true, flood:true, __routing_ttl:1}) as Promise + } + + public compileHelloMessage(ttl = 6) { + if (!Runtime.endpoint || Runtime.endpoint == LOCAL_ENDPOINT) return; + const keys = Crypto.getOwnPublicKeysExported(); + return Compiler.compile('?', [keys], {type:ProtocolDataType.HELLO, sign:false, flood:true, __routing_ttl:ttl}) as Promise; + } + + + private setDefaultInterface(defaultInterface: CommunicationInterface) { + this.#defaultInterface = defaultInterface + this.defaultSocket = defaultInterface.getSockets().values().next().value + } + /** * Returns true when the socket is registered. * Returns true when the endpoint is registered for the socket (if an endpoint is provided). @@ -249,6 +347,45 @@ export class CommunicationHubHandler { else return this.#registeredSockets.has(socket as ConnectedCommunicationInterfaceSocket) } + public handleOfflineEndpoint(endpoint: Endpoint) { + for (const socket of this.iterateEndpointSockets(endpoint, false, false)) { + // direct connection endpoint offline, should not happen + if (socket.endpoint == endpoint) { + // this.#logger.error("Direct socket endpoint "+endpoint.toString()+" is not reachable, but socket is still connected."); + // (socket as CommunicationInterfaceSocket).connected = false; + } + // indirect endpoint offline, remove socket registration + else { + this.#logger.debug("Indirect socket endpoint "+endpoint.toString()+" is offline, removing socket registration."); + this.unregisterSocket(socket, endpoint); + } + } + } + + /** + * Returns true when the endpoint or a matching instance endpoint is directly registered for the socket. + */ + public hasDirectSocket(endpoint: Endpoint) { + // check if exact endpoint instance is registered + if (this._hasDirectSocket(endpoint)) return true; + + // find socket that matches instance if main endpoint + if (endpoint.main === endpoint) { + const instances = [...this.#activeEndpointInstances.get(endpoint)??[]]; + for (const instance of instances) { + if (this._hasDirectSocket(instance)) return true; + } + } + + return false + } + + private _hasDirectSocket(endpoint: Endpoint) { + // check if exact endpoint instance is registered as direct socket + return this.iterateEndpointSockets(endpoint, true, false) + .next().done === false; + } + /** * Method called by CommunicationInterfaceSockets when they receive a datex block * @param data @@ -311,18 +448,33 @@ export class CommunicationHubHandler { } } - if (this.#defaultSocket !== excludeSocket) - return this.#defaultSocket; + if (this.defaultSocket !== excludeSocket) + return this.defaultSocket; } private findMatchingEndpointSocket(endpoint: Endpoint, excludeSocket?: CommunicationInterfaceSocket) { - for (const socket of this.#endpointSockets.get(endpoint) ?? []) { + for (const socket of this.iterateEndpointSockets(endpoint, false, true)) { if (socket === excludeSocket) continue; return socket; } } + private *iterateEndpointSockets(endpoint: Endpoint, onlyDirect = true, onlyOutgoing = true) { + for (const socket of this.#endpointSockets.get(endpoint) ?? []) { + if (onlyDirect && socket.endpoint !== endpoint) continue; + if (onlyOutgoing && !socket.canSend) continue; + yield socket; + } + } + + private *iterateSockets(onlyOutgoing = true) { + for (const socket of this.#registeredSockets.keys()) { + if (onlyOutgoing && !socket.canSend) continue; + yield socket; + } + } + /** * Method called to send a datex block to a receiver (or as a broadcast) * @param dxb @@ -333,13 +485,19 @@ export class CommunicationHubHandler { if (data.receivers == Datex.BROADCAST) return this.datexBroadcastOut(data); const receivers = data.receivers instanceof Endpoint ? [data.receivers] : [...data.receivers]; - const outGroups = new Map( - // group receivers by socket - [...Map.groupBy( + const outGroups = receivers.length == 1 ? + + // single endpoint shortcut + new Map([[this.getPreferredSocketForEndpoint(receivers[0]), new Disjunction(...receivers)]]) : + + // group for multiple endpoints + new Map( + // group receivers by socket + [...Map.groupBy( // map receivers to sockets receivers.map(r => ({endpoint: r, socket: this.getPreferredSocketForEndpoint(r)}), - ), ({socket}) => socket) - .entries() + ), ({socket}) => socket + ).entries() ] // map endpoint object arrays to Set .map(([k, v]) => [k, new Disjunction(...v.map(({endpoint}) => endpoint))] as const) @@ -358,7 +516,7 @@ export class CommunicationHubHandler { // throw error if message could not be sent to some receivers if (outGroups.has(undefined)) { const endpointsString = [...outGroups.get(undefined)!].map(e => e.toString()).join(", ") - throw new NetworkError("No socket for endpoints " + endpointsString); + throw new NetworkError("No socket for " + endpointsString); } await Promise.all(promises); @@ -372,7 +530,7 @@ export class CommunicationHubHandler { if (reachedEndpoints.has(socket.endpoint)) continue; reachedEndpoints.add(socket.endpoint); - socket.sendBlock(data.dxb); + socket.sendBlock(data.dxb).catch(console.error); } } diff --git a/network/communication-interface.ts b/network/communication-interface.ts index 958b60e7..a1816b7e 100644 --- a/network/communication-interface.ts +++ b/network/communication-interface.ts @@ -33,6 +33,37 @@ function getIdentifier(properties?: InterfaceProperties) { return `${properties.type}${properties.name? ` (${properties.name})` : ''}` } +class EndpointConnectEvent extends Event { + constructor(public endpoint: Endpoint) { + super('connect'); + } +} +class EndpointDisconnectEvent extends Event { + constructor(public endpoint: Endpoint) { + super('disconnect') + } +} + +interface CustomEventMap { + "connect": EndpointConnectEvent + "disconnect": EndpointDisconnectEvent +} + +/** + * A connected communication interface socket that is registered in the communication hub + * and can be used to send and receive messages + */ +export type ConnectedCommunicationInterfaceSocket = CommunicationInterfaceSocket & { + connected: true, + endpoint: Endpoint, + interfaceProperties: InterfaceProperties +} + + +type ReadonlySet = Set & {add: never, delete: never, clear: never} + + + export abstract class CommunicationInterfaceSocket extends EventTarget { /** * Endpoint is only set once. If the endpoint changes, a new socket is created @@ -42,6 +73,7 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { #destroyed = false; #opened = false; + clone?: CommunicationInterfaceSocket static defaultLogger = new Logger("CommunicationInterfaceSocket") public logger = CommunicationInterfaceSocket.defaultLogger; @@ -62,6 +94,7 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { return this.#connected } set connected(connected) { + if (connected === this.#connected) return; // no change if (this.#destroyed) throw new Error("Cannot change connected state of destroyed socket.") this.#connected = connected this.#updateRegistration(); @@ -92,12 +125,12 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { this.#opened = true; } - if (!this.#endpoint || this.#destroyed) return; if (this.#connected) { if (!this.isRegistered) { this.#connectTimestamp = Date.now() + this.dispatchEvent(new EndpointConnectEvent(this.#endpoint)) communicationHub.handler.registerSocket(this as ConnectedCommunicationInterfaceSocket) } } @@ -108,8 +141,25 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { } } + public get canSend() { + return this.interfaceProperties?.direction !== InterfaceDirection.IN + } + public get canReceive() { + return this.interfaceProperties?.direction !== InterfaceDirection.OUT + } + + public sendHello(dxb: ArrayBuffer) { + if (!Runtime.endpoint || Runtime.endpoint == LOCAL_ENDPOINT) return; + this.sendBlock(dxb).catch(console.error) + } + + public sendGoodbye(dxb: ArrayBuffer) { + if (!Runtime.endpoint || Runtime.endpoint == LOCAL_ENDPOINT) return; + this.sendBlock(dxb).catch(console.error) + } + public async sendBlock(dxb: ArrayBuffer) { - if (this.interfaceProperties?.direction === InterfaceDirection.IN) throw new Error("Cannot send from an IN interface socket"); + if (!this.canSend) throw new Error("Cannot send from an IN interface socket"); if (this.#destroyed) throw new Error("Cannot send from destroyed socket.") if (!this.connected) throw new Error("Cannot send from disconnected socket"); @@ -122,10 +172,10 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { } protected async receive(dxb: ArrayBuffer) { - console.log("receive",dxb) - if (this.interfaceProperties?.direction === InterfaceDirection.OUT) throw new Error("Cannot receive on an OUT interface socket"); + if (!this.canReceive) throw new Error("Cannot receive on an OUT interface socket"); if (this.#destroyed) throw new Error("Cannot receive on destroyed socket"); if (!this.connected) throw new Error("Cannot receive on disconnected socket"); + console.log("RECEIVE on socket " + this.endpoint) let header: dxb_header; try { @@ -138,13 +188,28 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { console.error(e); return; } + console.log("RECEIVED from " + header.sender) + + // a cloned socket was already created in the meantime, handle header in clone + if (this.clone) { + console.log("using clone for ", header); + this.clone.handleReceiveHeader(header) + } + // handle header in this socket + else this.handleReceiveHeader(header) + } + + protected handleReceiveHeader(header: dxb_header) { + if (this.#destroyed) throw new Error("Cannot receive on destroyed socket"); + if (!this.connected) throw new Error("Cannot receive on disconnected socket"); // listen for GOODBYE messages if (this.endpoint) { if (header.type == ProtocolDataType.GOODBYE && header.sender === this.endpoint) { + console.log("RECEIVE goodbye from " + this.endpoint) this.connected = false this.#destroyed = true - this.dispatchEvent(new CustomEvent('endpoint-disconnect')) + this.dispatchEvent(new EndpointDisconnectEvent(this.endpoint)) } // message from another endpoint, record as indirect socket connection else if (header.sender !== this.endpoint && !communicationHub.handler.hasSocket(this as ConnectedCommunicationInterfaceSocket, header.sender)) { @@ -156,6 +221,7 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { } // detect new endpoint else if (header.sender) { + console.log("new endpoint detected " + header.sender) this.endpoint = header.sender } } @@ -174,26 +240,18 @@ export abstract class CommunicationInterfaceSocket extends EventTarget { toString() { return getIdentifier(this.interfaceProperties) } -} - -/** - * A connected communication interface socket that is registered in the communication hub - * and can be used to send and receive messages - */ -export type ConnectedCommunicationInterfaceSocket = CommunicationInterfaceSocket & { - connected: true, - endpoint: Endpoint, - interfaceProperties: InterfaceProperties -} -type ReadonlySet = Set & {add: never, delete: never, clear: never} + declare addEventListener: (type: K, listener: (ev: CustomEventMap[K]) => void) => void; + declare removeEventListener: (type: K, listener: (ev: CustomEventMap[K]) => void) => void; + declare dispatchEvent: (ev: CustomEventMap[K]) => boolean; +} /** * Base class for all DATEX communication interfaces */ -export abstract class CommunicationInterface { +export abstract class CommunicationInterface extends EventTarget { protected logger = new Logger(this.constructor.name) @@ -210,6 +268,7 @@ export abstract class CommunicationInterface } + + #connectHandler: ((endpoint: EndpointConnectEvent) => void)|null|undefined + + /** + * Event handler that is called when a new endpoint is connected to a socket on this interface + */ + set onConnect(handler: ((endpoint: EndpointConnectEvent) => void)|null|undefined) { + if (handler) { + this.#connectHandler = handler + this.addEventListener("connect", handler) + } + else { + if (this.#connectHandler) this.removeEventListener("connect", this.#connectHandler) + this.#connectHandler = handler + } + } + async #reconnect() { if (this.#connecting) return; this.#connecting = true; @@ -247,29 +323,31 @@ export abstract class CommunicationInterface { + protected async addSocket(socket: Socket) { + if (this.#sockets.has(socket)) throw new Error("Socket already part of interface sockets.") + + socket.addEventListener('disconnect', e => { + this.dispatchEvent(new EndpointDisconnectEvent(e.endpoint)) // remove old socket this.removeSocket(socket) // clone and add new socket const newSocket = this.cloneSocket(socket); + socket.clone = newSocket; this.addSocket(newSocket); }) + socket.addEventListener('connect', e => { + this.dispatchEvent(new EndpointConnectEvent(e.endpoint)) + }) + + socket.interfaceProperties = this.properties + socket.logger = this.logger; + socket.connected = true; // adds sockets to communication hub this.#sockets.add(socket); // send HELLO message - if (this.properties.direction !== InterfaceDirection.OUT) - this.sendHelloViaSocket(socket); - } - - protected async sendHelloViaSocket(socket: Socket) { - // TODO: sending keys is only workaround - const keys = Crypto.getOwnPublicKeysExported(); - const message = await Compiler.compile('?', [keys], {type:ProtocolDataType.HELLO, sign:false, flood:true, __routing_ttl:10}) as ArrayBuffer; - this.logger.debug("saying hello via " + socket) - await socket.sendBlock(message); + if (socket.canSend) { + const helloMessage = await communicationHub.handler.compileHelloMessage() + if (helloMessage) socket.sendHello(helloMessage) + } } /** @@ -283,6 +361,7 @@ export abstract class CommunicationInterface(type: K, listener: (ev: CustomEventMap[K]) => void) => void; + declare removeEventListener: (type: K, listener: (ev: CustomEventMap[K]) => void) => void; + declare dispatchEvent: (ev: CustomEventMap[K]) => boolean; } \ No newline at end of file diff --git a/network/communication-interfaces/local-loopback-interface.ts b/network/communication-interfaces/local-loopback-interface.ts index 6f7dbba8..a6cbb217 100644 --- a/network/communication-interfaces/local-loopback-interface.ts +++ b/network/communication-interfaces/local-loopback-interface.ts @@ -8,13 +8,19 @@ export class LocalLoopbackInterfaceSocket extends CommunicationInterfaceSocket { close() {} send(dxb: ArrayBuffer) { - console.log("local",dxb) Runtime.datexIn({ dxb, socket: this }) return true; } + + override async sendHello(_dxb:ArrayBuffer) { + // ignore + } + override async sendGoodbye(_dxb:ArrayBuffer) { + // ignore + } } export class LocalLoopbackInterface extends CommunicationInterface { @@ -36,6 +42,7 @@ export class LocalLoopbackInterface extends CommunicationInterface { + if (endpoint === LOCAL_ENDPOINT) return; // remove socket for previous endpoint if (this.#currentSocket) this.removeSocket(this.#currentSocket) // add new socket for endpoint diff --git a/network/communication-interfaces/web-socket-client-interface.ts b/network/communication-interfaces/web-socket-client-interface.ts index 863cf275..9ddbcecd 100644 --- a/network/communication-interfaces/web-socket-client-interface.ts +++ b/network/communication-interfaces/web-socket-client-interface.ts @@ -48,6 +48,9 @@ export class WebSocketClientInterface extends CommunicationInterface((resolve) => { + windowInterface.addEventListener("connect", e => { + resolve({ + window: newWindow, + endpoint: e.endpoint + }) + }) + if (connectionTimeout!=null && isFinite(connectionTimeout)) { + setTimeout(() => { + newWindow.close(); + resolve({window: newWindow, endpoint: null}) + }, connectionTimeout); + } + }) } } \ No newline at end of file diff --git a/network/supranet.ts b/network/supranet.ts index 64d5ea04..0093caa9 100644 --- a/network/supranet.ts +++ b/network/supranet.ts @@ -1,34 +1,30 @@ /** ╔══════════════════════════════════════════════════════════════════════════════════════╗ - ║ Datex Cloud - Entrypoint ║ + ║ unyt.org Supranet connection handler ║ ╠══════════════════════════════════════════════════════════════════════════════════════╣ - ║ Visit https://docs.unyt.org/datex for more information ║ + ║ Visit https://docs.unyt.org/manual/datex/supranet-networking for more information ║ ╠═════════════════════════════════════════╦════════════════════════════════════════════╣ - ║ © 2021 unyt.org ║ ║ + ║ © 2024 unyt.org ║ ║ ╚═════════════════════════════════════════╩════════════════════════════════════════════╝ */ -import InterfaceManager, { CommonInterface } from "./client.ts" -import { Compiler } from "../compiler/compiler.ts"; +import { CommonInterface } from "./client.ts" import { Runtime } from "../runtime/runtime.ts"; import { Crypto } from "../runtime/crypto.ts"; import {client_type} from "../utils/constants.ts"; -import { Endpoint, filter_target_name_id, Target } from "../types/addressing.ts"; - - +import { Endpoint } from "../types/addressing.ts"; import { Logger } from "../utils/logger.ts"; -import { ProtocolDataType } from "../compiler/protocol_types.ts"; -import { buffer2hex } from "../utils/utils.ts"; import { endpoint_config } from "../runtime/endpoint_config.ts"; import { endpoint_name, UnresolvedEndpointProperty } from "../datex_all.ts"; import { Datex } from "../mod.ts"; import { Storage } from "../runtime/storage.ts"; -import { sendDatexViaHTTPChannel } from "./datex-http-channel.ts"; +import { WebSocketClientInterface } from "./communication-interfaces/web-socket-client-interface.ts"; +import { communicationHub } from "./communication-hub.ts"; + const logger = new Logger("DATEX Supranet"); -// entry point to connect to the datex network export class Supranet { static available_channel_types:string[] = []; // all available interface channel types, sorted by preference @@ -39,22 +35,6 @@ export class Supranet { static #initialized = false; static get initialized(){return this.#initialized} - // add listeners for interface changes - private static listeners_set = false; - private static setListeners(){ - if (this.listeners_set) return; - this.listeners_set = true; - // say hello when (re)connected - InterfaceManager.onInterfaceConnected((i)=>{ - logger.debug("interface connected: "+ i.endpoint + " - " + i.type); - if (i.type != "local") this.sayHello(i.endpoint) - }) - InterfaceManager.onInterfaceDisconnected((i)=>{ - logger.debug("interface disconnected: "+ i.endpoint + " - " + i.type); - // TODO: validate this - if (!InterfaceManager.active_interfaces.size) this.#connected = false; - }) - } // connect without cache and random endpoint id public static connectAnonymous(){ @@ -66,7 +46,7 @@ export class Supranet { return this.connect(endpoint, false); } - // connect to cloud, say hello with public key + // connect to Supranet // if local_cache=false, a new endpoint is created and not saved in the cache, even if an endpoint is stored in the cache // TODO problem: using same keys as stored endpoint! public static async connect(endpoint?:Endpoint|UnresolvedEndpointProperty, local_cache?: boolean, sign_keys?:[ArrayBuffer|CryptoKey,ArrayBuffer|CryptoKey], enc_keys?:[ArrayBuffer|CryptoKey,ArrayBuffer|CryptoKey], via_node?:Endpoint) { @@ -91,13 +71,11 @@ export class Supranet { if (this.#connected && endpoint === Runtime.endpoint) { const switched = shouldSwitchInstance ? await this.handleSwitchToInstance() : false; logger.success("Connected to the supranet as " + endpoint) - if (!switched) this.sayHelloToAllInterfaces(); return true; } if (alreadyConnected) { this.#connected = true; - this.sayHelloToAllInterfaces(); if (shouldSwitchInstance) await this.handleSwitchToInstance(); return true; } @@ -109,11 +87,6 @@ export class Supranet { } - private static sayHelloToAllInterfaces() { - for (const i of InterfaceManager.active_interfaces) { - if (i.type != "local") this.sayHello(i.endpoint) - } - } private static shouldSwitchInstance(endpoint: Endpoint) { // return false; @@ -160,14 +133,12 @@ export class Supranet { Runtime.init(instance); endpoint_config.endpoint = instance; endpoint_config.save(); - this.sayHelloToAllInterfaces(); logger.success("Switched to endpoint instance " + instance) this.handleConnect(); return true; } catch { logger.error("Could not determine endpoint instance (request error)"); - this.sayHelloToAllInterfaces(); this.handleConnect(); } } @@ -177,13 +148,8 @@ export class Supranet { private static async _connect(via_node?:Endpoint, handleOnConnect = true) { // find node for available channel - const [node, channel_type] = await this.getNode(via_node) - - // TODO: clean disconnect with GOODBYE? Never disconnect interfaces? - // await InterfaceManager.disconnect() // first disconnect completely - const connected = await InterfaceManager.connect(channel_type, node) - - Runtime.setMainNode(node); + const [node, channel_type] = this.getNode(via_node) + const connected = await this.connectToEndpoint(node, channel_type) if (!connected) logger.error("connection failed") else if (handleOnConnect) await this.handleConnect(); @@ -200,17 +166,55 @@ export class Supranet { static getNode(use_node?:Endpoint) { // channel types? - // @ts-ignore if (globalThis.WebSocketStream || client_type!="browser") this.available_channel_types.push("websocketstream") this.available_channel_types.push("websocket"); // find node for available channel - const [node, channel_type] = endpoint_config.getNodeWithChannelType(this.available_channel_types, use_node); + const [node, channel_type] = endpoint_config.getNodeWithInterfaceType(this.available_channel_types, use_node); if (!node) throw ("Cannot find a node that support any channel type of: " + this.available_channel_types + (use_node ? " via " + use_node : '')); if (!channel_type) throw("No channel type for node: " + node); - return <[Endpoint,string]> [node, channel_type] + return [node, channel_type] as const; } + + + /** + * Connects to a endpoint via an available interface if a known + * interface exists for the endpoint + * @param endpoint endpoint to connect to + * @param interfaceType optional interface type to connect with + * @returns true if a connection could be established + */ + public static async connectToEndpoint(endpoint: Endpoint, interfaceType?: string, setAsDefault = true): Promise { + + // check if interface is available + const info = endpoint.getInterfaceChannelInfo(interfaceType); + if (info) { + console.log("info",info) + // websocket + if (interfaceType == "websocket") { + if (!(info instanceof URL || typeof info === "string")) { + logger.error("Invalid data for websocket interface, expected string or URL"); + return false; + } + const webSocketInterface = new WebSocketClientInterface(info instanceof URL ? info.origin : info) + await communicationHub.addInterface(webSocketInterface, setAsDefault); + return true; + } + // TODO: more interfaces + else { + logger.error("Interface type not supported: " + interfaceType); + return false; + } + } + else { + return false; + } + + } + + + private static handleConnect() { for (const listener of this.#connectListeners) listener(); if (this.onConnect) this.onConnect() @@ -218,7 +222,7 @@ export class Supranet { // @override public static onConnect = ()=>{ - logger.success("Connected as **"+Runtime.endpoint+"** to the Supranet via **" + CommonInterface.default_interface.endpoint + "** (" + CommonInterface.default_interface.type + ")" ) + logger.success("Connected as **"+Runtime.endpoint+"** to the Supranet via **" + communicationHub.handler.defaultSocket?.endpoint + "** (" + communicationHub.handler.defaultSocket?.toString() + ")" ) } static #connectListeners = new Set<()=>void>() @@ -274,8 +278,6 @@ export class Supranet { return this._init(endpoint, local_cache, sign_keys, enc_keys, keys); } - static #interfaces_initialized = false - private static async _init(endpoint:Endpoint, local_cache = !endpoint_config.temporary, sign_keys?:[ArrayBuffer|CryptoKey,ArrayBuffer|CryptoKey], enc_keys?:[ArrayBuffer|CryptoKey,ArrayBuffer|CryptoKey], keys?:Crypto.ExportedKeySet) { // load/create keys, even if endpoint was provided? @@ -312,13 +314,6 @@ export class Supranet { // bind keys to initialized endpoint (already done for @@local in Crypto.loadOwnKeys) Crypto.saveOwnPublicKeysInEndpointKeyMap() - // setup interface manager - if (!this.#interfaces_initialized) { - this.#interfaces_initialized = true; - await InterfaceManager.init() - this.setListeners(); - } - this.#initialized = true; return endpoint; @@ -376,40 +371,5 @@ export class Supranet { return keys; } - - // important network methods - - public static sayHello(node:Endpoint = Runtime.main_node){ - // TODO REPLACE, only temporary as placeholder to inform router about own public keys - const keys = Crypto.getOwnPublicKeysExported(); - logger.debug("saying hello as " + Runtime.endpoint) - Runtime.datexOut(['?', [keys], {type:ProtocolDataType.HELLO, sign:false, flood:true, __routing_ttl:10}], undefined, undefined, false, false) - // send with plain endpoint id as sender - // if (Runtime.endpoint.id_endpoint !== Runtime.endpoint) Runtime.datexOut(['?', [keys], {type:ProtocolDataType.HELLO, sign:false, flood:true, force_id:true, __routing_ttl:1}], undefined, undefined, false, false) - } - - // ping all endpoints with same base (@endpoint/*) - public static async findOnlineEndpoints(endpoint:Endpoint){ - // TODO - //await this.pingEndpoint(Target.get(endpoint.toString())) - } - - - // get DATEX roundtime/ping for endpoint - public static async pingEndpoint(endpoint_or_string:string|Endpoint, sign=false, encrypt=false) { - let endpoint = endpoint_or_string instanceof Endpoint ? endpoint_or_string : Endpoint.get(endpoint_or_string); - const start_time = new Date().getTime(); - const half_time = (await Runtime.datexOut(['