From 0f5565debff086f00774219d5388c21eab4820b7 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Sun, 12 Sep 2021 16:40:40 -0400 Subject: [PATCH] Load() functionality --- utils/GunSmith/GunSmith.js | 47 ++++++++++++++++++++++++++++++++++---- utils/GunSmith/Smith.ts | 21 ++++++++++++++++- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/utils/GunSmith/GunSmith.js b/utils/GunSmith/GunSmith.js index e2032f66..0d452707 100644 --- a/utils/GunSmith/GunSmith.js +++ b/utils/GunSmith/GunSmith.js @@ -23,6 +23,9 @@ const pathToListeners = {} */ const pathToMapListeners = {} +/** @type {Record} */ +const idToLoadListener = {} + /** * Path to pending puts. Oldest to newest * @type {Record} @@ -33,6 +36,16 @@ const pendingPuts = {} * @param {Smith.GunMsg} msg */ const handleMsg = msg => { + if (msg.type === 'load') { + const { data, id, key } = msg + + const listener = idToLoadListener[id] + + if (listener) { + listener(data, key) + delete idToLoadListener[id] + } + } if (msg.type === 'on') { const { data, path } = msg @@ -189,7 +202,7 @@ const forge = () => { * @returns {GunT.GUNNode} */ function createReplica(path, afterMap = false) { - /** @type {GunT.Listener[]} */ + /** @type {(GunT.Listener|GunT.LoadListener)[]} */ const listenersForThisRef = [] return { @@ -211,6 +224,28 @@ function createReplica(path, afterMap = false) { } return createReplica(path + '>' + key) }, + load(cb) { + // Dumb implementation. We must move away from load() anyways. + if (afterMap) { + throw new Error('Cannot call load() after map() on a GunSmith node') + } + if (cb) { + listenersForThisRef.push(cb) + + const id = uuid() + + idToLoadListener[id] = cb + + /** @type {Smith.SmithMsgLoad} */ + const msg = { + id, + path, + type: 'load' + } + currentGun.send(msg) + } + return this + }, map() { if (afterMap) { throw new Error('Cannot call map() after map() on a GunSmith node') @@ -218,15 +253,19 @@ function createReplica(path, afterMap = false) { return createReplica(path, true) }, off() { - if (afterMap) { - throw new Error('Cannot call off() after map() on a GunSmith node') - } for (const l of listenersForThisRef) { // eslint-disable-next-line no-multi-assign const listeners = pathToListeners[path] || (pathToListeners[path] = new Set()) + // eslint-disable-next-line no-multi-assign + const mapListeners = + pathToMapListeners[path] || (pathToMapListeners[path] = new Set()) + + // @ts-expect-error listeners.delete(l) + // @ts-expect-error + mapListeners.delete(l) } }, on(cb) { diff --git a/utils/GunSmith/Smith.ts b/utils/GunSmith/Smith.ts index 8536b4c5..c47402bc 100644 --- a/utils/GunSmith/Smith.ts +++ b/utils/GunSmith/Smith.ts @@ -25,6 +25,12 @@ namespace Smith { type: 'on' } + export interface SmithMsgLoad { + id: string + path: string + type: 'load' + } + export interface SmithMsgMapOn { path: string type: 'map.on' @@ -41,6 +47,7 @@ namespace Smith { | SmithMsgInit | SmithMsgAuth | SmithMsgOn + | SmithMsgLoad | SmithMsgMapOn | SmithMsgPut | BatchSmithMsg @@ -65,6 +72,13 @@ namespace Smith { type: 'map.on' } + export interface GunMsgLoad { + id: string + data: GunT.LoadListenerData + key: string + type: 'load' + } + export interface GunMsgPut { ack: GunT.Ack id: string @@ -72,5 +86,10 @@ namespace Smith { type: 'put' } - export type GunMsg = GunMsgAuth | GunMsgOn | GunMsgMapOn | GunMsgPut + export type GunMsg = + | GunMsgAuth + | GunMsgOn + | GunMsgMapOn + | GunMsgLoad + | GunMsgPut }