Skip to content

Commit

Permalink
Fix interfaces and add disconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
benStre committed Nov 13, 2023
1 parent c6dc6e7 commit 34ffafc
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 105 deletions.
16 changes: 5 additions & 11 deletions datex_short.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

// shortcut functions
// import { Datex } from "./datex.ts";
import { baseURL, Runtime, PrecompiledDXB, Type, Pointer, Ref, PointerProperty, primitive, any_class, Target, IdEndpoint, TransformFunctionInputs, AsyncTransformFunction, TransformFunction, TextRef, Markdown, DecimalRef, BooleanRef, IntegerRef, MinimalJSRef, RefOrValue, PartialRefOrValueObject, datex_meta, ObjectWithDatexValues, Compiler, endpoint_by_endpoint_name, endpoint_name, Storage, compiler_scope, datex_scope, DatexResponse, target_clause, ValueError, logger, Class, getUnknownMeta, Endpoint, INSERT_MARK, CollapsedValueAdvanced, CollapsedValue, SmartTransformFunction, compiler_options, activePlugins, METADATA, handleDecoratorArgs, RefOrValueObject, PointerPropertyParent, InferredPointerProperty } from "./datex_all.ts";
import { baseURL, Runtime, PrecompiledDXB, Type, Pointer, Ref, PointerProperty, primitive, any_class, Target, IdEndpoint, TransformFunctionInputs, AsyncTransformFunction, TransformFunction, TextRef, Markdown, DecimalRef, BooleanRef, IntegerRef, MinimalJSRef, RefOrValue, PartialRefOrValueObject, datex_meta, ObjectWithDatexValues, Compiler, endpoint_by_endpoint_name, endpoint_name, Storage, compiler_scope, datex_scope, DatexResponse, target_clause, ValueError, logger, Class, getUnknownMeta, Endpoint, INSERT_MARK, CollapsedValueAdvanced, CollapsedValue, SmartTransformFunction, compiler_options, activePlugins, METADATA, handleDecoratorArgs, RefOrValueObject, PointerPropertyParent, InferredPointerProperty, RefLike } from "./datex_all.ts";

/** make decorators global */
import {property as _property, sync as _sync, endpoint as _endpoint, template as _template, jsdoc as _jsdoc} from "./datex_all.ts";
Expand All @@ -12,6 +12,8 @@ import { AssertionError } from "./types/errors.ts";
import { getCallerFile, getCallerInfo, getMeta } from "./utils/caller_metadata.ts";
import { eternals, getLazyEternal, waitingEternals, waitingLazyEternals } from "./utils/eternals.ts";

import {instance} from "./js_adapter/js_class_adapter.ts";
export {instance} from "./js_adapter/js_class_adapter.ts";

declare global {
const property: typeof _property;
Expand Down Expand Up @@ -214,27 +216,19 @@ export async function script(dx:string|TemplateStringsArray|PrecompiledDXB, data
}


// generate a instance of a JS class / DATEX Type by casting
export function instance<T>(fromClass:{new(...params:any[]):T}, properties?:PartialRefOrValueObject<T>): T
export function instance<T>(fromType:Type<T>, properties?:PartialRefOrValueObject<T>): T
export function instance<T>(fromClassOrType:{new(...params:any[]):T}|Type<T>, properties?:PartialRefOrValueObject<T>): T {
if (fromClassOrType instanceof Type) return fromClassOrType.cast(properties);
else return Type.getClassDatexType(fromClassOrType).cast(properties)
}

// generate a pointer for an object and returns the proxified object or the primitive pointer
/**
* Returns a pointer property (live ref that points to the property of a Map or Object)
* @param parentValue Map or Object
* @param property property name
*/
export function pointer<Key, Parent extends PointerPropertyParent<Key,unknown>>(parentValue:Ref<Parent>, property:Key): PointerProperty<Parent extends Map<unknown, infer MV> ? MV : Parent[Key&keyof Parent]> // defined 2x with Ref<Parent> and Parent for correct type inference
export function pointer<Key, Parent extends PointerPropertyParent<Key,unknown>>(parentValue:RefLike<Parent>, property:Key): PointerProperty<Parent extends Map<unknown, infer MV> ? MV : Parent[Key&keyof Parent]> // defined 2x with Ref<Parent> and Parent for correct type inference
export function pointer<Key, Parent extends PointerPropertyParent<Key,unknown>>(parentValue:Parent, property:Key): PointerProperty<Parent extends Map<unknown, infer MV> ? MV : Parent[Key&keyof Parent]>
/**
* Creates a new pointer from a value
* @param value
*/
export function pointer<T>(value:Ref<T>): MinimalJSRef<T> // defined 2x with Ref<T> and T for correct type inference
export function pointer<T>(value:RefLike<T>): MinimalJSRef<T> // defined 2x with Ref<T> and T for correct type inference
export function pointer<T>(value:T): MinimalJSRef<T>
export function pointer<T>(value:RefOrValue<T>, property?:unknown): unknown {

Expand Down
14 changes: 6 additions & 8 deletions functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/


import { AsyncTransformFunction, BooleanRef, CollapsedValue, CollapsedValueAdvanced, Decorators, INSERT_MARK, METADATA, MaybeObjectRef, MinimalJSRef, Pointer, Ref, RefOrValue, Runtime, SmartTransformFunction, TransformFunction, TransformFunctionInputs, handleDecoratorArgs, primitive } from "./datex_all.ts";
import { AsyncTransformFunction, BooleanRef, CollapsedValue, CollapsedValueAdvanced, Decorators, INSERT_MARK, METADATA, MaybeObjectRef, MinimalJSRef, Pointer, Ref, RefLike, RefOrValue, Runtime, SmartTransformFunction, TransformFunction, TransformFunctionInputs, handleDecoratorArgs, primitive } from "./datex_all.ts";
import { Datex } from "./mod.ts";
import { IterableHandler } from "./utils/iterable-handler.ts";

Expand All @@ -21,7 +21,7 @@ import { IterableHandler } from "./utils/iterable-handler.ts";
* y.val // 10
* ```
*/
export function always<const T,V extends TransformFunctionInputs>(transform:SmartTransformFunction<T>): CollapsedValueAdvanced<Pointer<T>, false, false, CollapsedValue<Pointer<T>>> // return signature from Value.collapseValue(Pointer.smartTransform())
export function always<T>(transform:SmartTransformFunction<T>): MinimalJSRef<T> // return signature from Value.collapseValue(Pointer.smartTransform())
/**
* Shortcut for datex `always (...)`
* @param script
Expand Down Expand Up @@ -175,16 +175,14 @@ export function map<T, U, O extends 'array'|'map' = 'array'>(iterable: Iterable<
* @param if_true value selected if true
* @param if_false value selected if false
*/
// export function toggle<T extends primitive>(value:Ref<boolean>, if_true:T, if_false:T):Pointer<T>
export function toggle<T>(value:Ref<boolean>, if_true:T, if_false:T): CollapsedValueAdvanced<Pointer<T>, false, false, CollapsedValue<Pointer<T>>>
export function toggle<T>(value:Ref<boolean>, if_true:T, if_false:T) {
export function toggle<T>(value:RefLike<boolean>, if_true:T, if_false:T): MinimalJSRef<T> {
return transform([value], v=>v?<any>if_true:<any>if_false,
// dx transforms not working correctly (with uix)
/*`
always (
if (${Runtime.valueToDatexString(value)}) (${Runtime.valueToDatexString(if_true)})
else (${Runtime.valueToDatexString(if_false)})
)`*/);
)`*/).js_value;
}


Expand All @@ -199,7 +197,7 @@ export const select = toggle;
* @param a input value
* @param b input value
*/
export function equals(a:unknown, b: unknown):Datex.Ref<boolean> {
export function equals<T,V>(a:RefLike<T>|T, b: RefLike<V>|V): T extends V ? (V extends T ? Datex.Pointer<boolean> : Datex.Pointer<false>) : Datex.Pointer<false> {
return transform([a, b], (a,b) => Datex.Ref.collapseValue(a, true, true) === Datex.Ref.collapseValue(b, true, true),
// dx transforms not working correctly (with uix)
/*`always (${Runtime.valueToDatexString(a)} === ${Runtime.valueToDatexString(b)})`*/) as any;
Expand All @@ -212,7 +210,7 @@ export function equals(a:unknown, b: unknown):Datex.Ref<boolean> {
* @param object the reference object
* @returns
*/
export function selectProperty<K extends string|number, V>(property:Ref<K>, object:Readonly<Record<K, V>>):MinimalJSRef<V> {
export function selectProperty<K extends string|number, V>(property:RefLike<K>, object:Readonly<Record<K, V>>):MinimalJSRef<V> {
return <MinimalJSRef<V>> transform([property], (v)=><any>object[<K>v]);
}

Expand Down
36 changes: 18 additions & 18 deletions iframes/iframe-com-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,7 @@ export class IFrameCommunicationInterface extends CommonInterface<[HTMLIFrameEle
this.logger.error("no IFrame or Window provided for IFrameCommunicationInterface");
return false;
}
globalThis.addEventListener("message", (event) => {
if (event.origin == this.otherOrigin) {
const data = event.data;

if (data instanceof ArrayBuffer) {
InterfaceManager.handleReceiveBlock(data, this.endpoint, this);
}

else if (data?.type == "INIT") {
this.endpoint = Target.get(data.endpoint) as Datex.Endpoint;

// if in parent: send INIT to iframe after initialized
if (this.iframe) this.sendInit();
}
}

})
globalThis.addEventListener("message", this.onReceive);

// if in ifram: send INIT to parent immediately
if (this.parentDocument)
Expand All @@ -71,12 +55,28 @@ export class IFrameCommunicationInterface extends CommonInterface<[HTMLIFrameEle
return true;
}

onReceive = (event: MessageEvent) => {
if (event.origin == this.otherOrigin) {
const data = event.data;
if (data instanceof ArrayBuffer) {
InterfaceManager.handleReceiveBlock(data, this.endpoint, this);
}
else if (data?.type == "INIT") {
this.endpoint = Target.get(data.endpoint) as Datex.Endpoint;

// if in parent: send INIT to iframe after initialized
if (this.iframe) this.sendInit();
}
}

}

private sendInit() {
this.other.postMessage({type:"INIT", endpoint:Datex.Runtime.endpoint.toString()}, this.otherOrigin);
}

public override disconnect() {

globalThis.removeEventListener("message", this.onReceive);
}

get other() {
Expand Down
5 changes: 3 additions & 2 deletions init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ export async function init() {
// init persistent memory
Runtime.persistent_memory = (await Storage.loadOrCreate("Datex.Runtime.MEMORY", ()=>new Map())).setAutoDefault(Object);


// init persistent subscriber cache
Runtime.subscriber_cache = (await Storage.loadOrCreate("Datex.Runtime.SUBSCRIBER_CACHE", ()=>new Map())).setAutoDefault(Set);
(async () => {
Runtime.subscriber_cache = (await Storage.loadOrCreate("Datex.Runtime.SUBSCRIBER_CACHE", ()=>new Map())).setAutoDefault(Set);
})()


if (!globalThis.NO_INIT) {
Expand Down
26 changes: 21 additions & 5 deletions js_adapter/js_class_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Logger } from "../utils/logger.ts";
import { Endpoint, endpoint_name, IdEndpoint, LOCAL_ENDPOINT, Target, target_clause } from "../types/addressing.ts";
import { context_kind, context_meta_getter, context_meta_setter, context_name } from "./legacy_decorators.ts";
import { Type } from "../types/type.ts";
import { getProxyFunction, getProxyStaticValue, Pointer, UpdateScheduler } from "../runtime/pointers.ts";
import { getProxyFunction, getProxyStaticValue, ObjectRef, Pointer, UpdateScheduler } from "../runtime/pointers.ts";
import { Error as DatexError, ValueError } from "../types/errors.ts";
import { Function as DatexFunction } from "../types/function.ts";
import { DatexObject } from "../types/object.ts";
Expand All @@ -39,6 +39,16 @@ const CONSTRUCT_OPTIONS = Symbol("CONSTRUCT_OPTIONS");
if (!Symbol['metadata']) Symbol['metadata'] = Symbol('metadata');
export const METADATA:unique symbol = Symbol['metadata'];


// generate a instance of a JS class / DATEX Type by casting
export function instance<T>(fromClass:{new(...params:any[]):T}, properties?:PartialRefOrValueObject<T>): T
export function instance<T>(fromType:Type<T>, properties?:PartialRefOrValueObject<T>): T
export function instance<T>(fromClassOrType:{new(...params:any[]):T}|Type<T>, properties?:PartialRefOrValueObject<T>): T {
if (fromClassOrType instanceof Type) return fromClassOrType.cast(properties);
else return Type.getClassDatexType(fromClassOrType).cast(properties)
}


/**
* List of decorators
*
Expand Down Expand Up @@ -1146,13 +1156,16 @@ interface DatexClass<T extends Object = any> {
room_id?: number;
}

type dc<T> = DatexClass<T> & T;
type dc<T extends Record<string,any>&{new (...args:unknown[]):unknown}> = DatexClass<T> & T & ((struct:InstanceType<T>) => InstanceType<T>);

export function datex_advanced<T>(_class:T) {
return <dc<T>> _class;
export function datexClass<T extends Record<string,any>&{new (...args:unknown[]):unknown}>(_class:T) {
return <dc<ObjectRef<T>>> _class;
}


/**
* @deprecated use datexClass
*/
export const datex_advanced = datexClass;

// extend a given class to create a auto-sync a class which autmatically creates synced objects (does not create a DATEX pseudo type configuration)
// if no type is provided, <ext:ClassName> is created as type by default
Expand All @@ -1178,6 +1191,9 @@ export function proxyClass<T extends { new(...args: any[]): any;}>(original_clas
return instance;
}
},
apply(target,_thisArg,argArray) {
return Pointer.createOrGet(instance(target, argArray[0])).js_value
},
getPrototypeOf(target) {
return original_class
}
Expand Down
22 changes: 19 additions & 3 deletions network/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ class WebsocketClientInterface extends CommonInterface {
// Connection opened
this.socket!.addEventListener('open', () => {
this.connecting = false;
if (this.protocol == 'ws' && this.host !== "localhost") this.logger.warn(`unsecure websocket connection to ${this.host}`)
if (this.protocol == 'ws' && !this.host.match(/localhost(:\d+)?/)) this.logger.warn(`unsecure websocket connection to ${this.host}`)
resolve(true);
});

Expand Down Expand Up @@ -708,7 +708,7 @@ export class InterfaceManager {
}

// create a new connection with a interface type (e.g. websocket, relayed...)
static async connect(channel_type:string, endpoint?:Endpoint, init_args?:any[], set_as_default_interface = true):Promise<boolean> {
static async connect(channel_type:string, endpoint?:Endpoint, init_args?:any[], set_as_default_interface = true, callback?: (interf: ComInterface, connected: boolean)=>void):Promise<boolean> {
this.logger.debug("connecting via interface: " + channel_type);

await this.init();
Expand All @@ -727,6 +727,8 @@ export class InterfaceManager {

this.enable();

callback?.(c_interface, res);

return res
}

Expand All @@ -737,9 +739,23 @@ export class InterfaceManager {
this.active_interfaces.add(i)
}
// remove an interface from the list
static removeInterface(i: ComInterface) {
static async removeInterface(i: ComInterface) {
if (!this.active_interfaces) this.active_interfaces = Pointer.createOrGet(new Set<ComInterface>()).js_value;
this.active_interfaces.delete(i)

for (const interfaces of CommonInterface.endpoint_connection_points.values()) {
interfaces.delete(i)
}
console.log(CommonInterface.endpoint_connection_points)

for (const interfaces of CommonInterface.indirect_endpoint_connection_points.values()) {
interfaces.delete(i)
}
for (const interfaces of CommonInterface.virtual_endpoint_connection_points.values()) {
interfaces.delete(i)
}

await i.disconnect()
}

// disconnected
Expand Down
1 change: 0 additions & 1 deletion runtime/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ export class Crypto {

// loads keys from network or cache
static requestKeys(endpoint:Endpoint):Promise<[CryptoKey?, CryptoKey?]> {
console.log("request keys ", endpoint)
// already requesting/loading keys for this endpoint
if (this.#waiting_key_requests.has(endpoint)) return <Promise<[CryptoKey, CryptoKey]>>this.#waiting_key_requests.get(endpoint);

Expand Down
Loading

0 comments on commit 34ffafc

Please sign in to comment.