| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-12-11 15:45:42 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-12-11 15:59:52 UTC |
| parent | c9c6ec9809bf121af7811488b7ba5bfd9ebf50b1 |
| xmpp/Chat.hx | +5 | -5 |
| xmpp/Map.js.hx | +80 | -0 |
| xmpp/persistence/browser.js | +2 | -2 |
| xmpp/queries/Push2Enable.hx | +2 | -2 |
diff --git a/xmpp/Chat.hx b/xmpp/Chat.hx index d8c99be..d478041 100644 --- a/xmpp/Chat.hx +++ b/xmpp/Chat.hx @@ -24,7 +24,7 @@ abstract class Chat { private var stream:GenericStream; private var persistence:Persistence; private var avatarSha1:Null<BytesData> = null; - private var presence:haxe.DynamicAccess<Presence> = {}; + private var presence:Map<String, Presence> = []; private var trusted:Bool = false; public var chatId(default, null):String; public var jingleSessions: Map<String, xmpp.jingle.Session> = []; @@ -400,7 +400,7 @@ class Channel extends Chat { if (err.name == "remote-server-not-found" || err.name == "remote-server-timeout") return checkRename(); // Timeout, retry later if (err.name == "item-not-found") return checkRename(); // Nick was changed? (shouldRefreshDisco ? refreshDisco : (cb)->cb())(() -> { - presence = {}; // About to ask for a fresh set + presence = []; // About to ask for a fresh set inSync = false; final desiredFullJid = JID.parse(chatId).withResource(client.displayName()); client.sendPresence( @@ -517,7 +517,7 @@ class Channel extends Chat { public function getParticipants() { final jid = JID.parse(chatId); - return presence.keys().map((resource) -> new JID(jid.node, jid.domain, resource).asString()); + return { iterator: () -> presence.keys() }.map((resource) -> new JID(jid.node, jid.domain, resource).asString()); } public function getParticipantDetails(participantId:String, callback:({photoUri:String, displayName:String})->Void) { @@ -688,14 +688,14 @@ class SerializedChat { public final chatId:String; public final trusted:Bool; public final avatarSha1:Null<BytesData>; - public final presence:haxe.DynamicAccess<Presence>; + public final presence:Map<String, Presence>; public final displayName:Null<String>; public final uiState:String; public final extensions:String; public final disco:Null<Caps>; public final klass:String; - public function new(chatId: String, trusted: Bool, avatarSha1: Null<BytesData>, presence: haxe.DynamicAccess<Presence>, displayName: Null<String>, uiState: Null<String>, extensions: Null<String>, disco: Null<Caps>, klass: String) { + public function new(chatId: String, trusted: Bool, avatarSha1: Null<BytesData>, presence: Map<String, Presence>, displayName: Null<String>, uiState: Null<String>, extensions: Null<String>, disco: Null<Caps>, klass: String) { this.chatId = chatId; this.trusted = trusted; this.avatarSha1 = avatarSha1; diff --git a/xmpp/Map.js.hx b/xmpp/Map.js.hx new file mode 100644 index 0000000..1f453c7 --- /dev/null +++ b/xmpp/Map.js.hx @@ -0,0 +1,80 @@ +package xmpp; + +import haxe.Constraints.IMap; +import js.lib.HaxeIterator; +import js.lib.Map as NativeMap; +using Lambda; + +// Use ES6 maps instead of Haxe maps +@:forward +abstract Map<K,V>(NativeMap<K,V>) { + public inline function set(k:K, v:V):Void { + this.set(k, v); + } + + public inline function exists(k:K):Bool { + return this.has(k); + } + + public inline function remove(k:K):Bool { + return this.delete(k); + } + + public inline function keys():Iterator<K> { + return new HaxeIterator(this.keys()); + } + + public inline function iterator():Iterator<V> { + return new HaxeIterator(this.values()); + } + + public inline function keyValueIterator():KeyValueIterator<K, V> { + return new HaxeKVIterator(this.entries()); + } + + // This shouldn't be needed but complier wants it... + public inline function flatMap<B>(f:(item:V)->Iterable<B>): Array<B> { + return { iterator: () -> this.iterator() }.flatMap(f); + } + + @:arrayAccess @:noCompletion public inline function arrayRead(k:K) { + return this.get(k); + } + + @:arrayAccess @:noCompletion public inline function arrayWrite(k:K, v:V):V { + this.set(k, v); + return v; + } + + @:from static function fromMap<K,V>(map:haxe.ds.Map<K,V>):Map<K, V> { + final result = new NativeMap(); + for (k => v in map) { + result.set(k, v); + } + return cast result; + } + + @:from static inline function fromArray<K,V>(iterable:Iterable<js.lib.KeyValue<K,V>>):Map<K, V> { + return cast new NativeMap(iterable); + } +} + +class HaxeKVIterator<K,V> { + final jsIterator: js.lib.Iterator<js.lib.KeyValue<K,V>>; + var lastStep: js.lib.Iterator.IteratorStep<js.lib.KeyValue<K,V>>; + + public inline function new(jsIterator: js.lib.Iterator<js.lib.KeyValue<K,V>>) { + this.jsIterator = jsIterator; + lastStep = jsIterator.next(); + } + + public inline function hasNext(): Bool { + return !lastStep.done; + } + + public inline function next(): { key: K, value: V } { + var v = lastStep.value; + lastStep = jsIterator.next(); + return { key: v.key, value: v.value }; + } +} diff --git a/xmpp/persistence/browser.js b/xmpp/persistence/browser.js index 4f6c922..fbf030c 100644 --- a/xmpp/persistence/browser.js +++ b/xmpp/persistence/browser.js @@ -167,7 +167,7 @@ exports.xmpp.persistence = { chatId: chat.chatId, trusted: chat.trusted, avatarSha1: chat.avatarSha1, - presence: Object.fromEntries(Object.entries(chat.presence || {}).map(([k, p]) => [k, { caps: p.caps?.ver(), mucUser: p.mucUser?.toString() }])), + presence: new Map([...chat.presence.entries()].map(([k, p]) => [k, { caps: p.caps?.ver(), mucUser: p.mucUser?.toString() }])), displayName: chat.displayName, uiState: chat.uiState?.toString(), extensions: chat.extensions?.toString(), @@ -186,7 +186,7 @@ exports.xmpp.persistence = { r.chatId, r.trusted, r.avatarSha1, - Object.fromEntries(await Promise.all(Object.entries(r.presence).map( + new Map(await Promise.all((r.presence instanceof Map ? [...r.presence.entries()] : Object.entries(r.presence)).map( async ([k, p]) => [k, new xmpp.Presence(p.caps && await new Promise((resolve) => this.getCaps(p.caps, resolve)), p.mucUser && xmpp.Stanza.parse(p.mucUser))] ))), r.displayName, diff --git a/xmpp/queries/Push2Enable.hx b/xmpp/queries/Push2Enable.hx index 649e423..e27c4f0 100644 --- a/xmpp/queries/Push2Enable.hx +++ b/xmpp/queries/Push2Enable.hx @@ -29,8 +29,8 @@ class Push2Enable extends GenericQuery { if (jwt_alg != null) { send.textTag("jwt-alg", jwt_alg); send.textTag("jwt-key", Base64.encode(jwt_key)); - for (claim in jwt_claims.keyValueIterator()) { - send.textTag("jwt-claim", claim.value, { name: claim.key }); + for (key => value in jwt_claims) { + send.textTag("jwt-claim", value, { name: key }); } } enable.up().up().up();