Load() functionality

This commit is contained in:
Daniel Lugo 2021-09-12 16:40:40 -04:00
parent b2d47c3ad6
commit 0f5565debf
2 changed files with 63 additions and 5 deletions

View file

@ -23,6 +23,9 @@ const pathToListeners = {}
*/ */
const pathToMapListeners = {} const pathToMapListeners = {}
/** @type {Record<string, GunT.LoadListener>} */
const idToLoadListener = {}
/** /**
* Path to pending puts. Oldest to newest * Path to pending puts. Oldest to newest
* @type {Record<string, Smith.PendingPut[]?>} * @type {Record<string, Smith.PendingPut[]?>}
@ -33,6 +36,16 @@ const pendingPuts = {}
* @param {Smith.GunMsg} msg * @param {Smith.GunMsg} msg
*/ */
const handleMsg = 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') { if (msg.type === 'on') {
const { data, path } = msg const { data, path } = msg
@ -189,7 +202,7 @@ const forge = () => {
* @returns {GunT.GUNNode} * @returns {GunT.GUNNode}
*/ */
function createReplica(path, afterMap = false) { function createReplica(path, afterMap = false) {
/** @type {GunT.Listener[]} */ /** @type {(GunT.Listener|GunT.LoadListener)[]} */
const listenersForThisRef = [] const listenersForThisRef = []
return { return {
@ -211,6 +224,28 @@ function createReplica(path, afterMap = false) {
} }
return createReplica(path + '>' + key) 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() { map() {
if (afterMap) { if (afterMap) {
throw new Error('Cannot call map() after map() on a GunSmith node') 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) return createReplica(path, true)
}, },
off() { off() {
if (afterMap) {
throw new Error('Cannot call off() after map() on a GunSmith node')
}
for (const l of listenersForThisRef) { for (const l of listenersForThisRef) {
// eslint-disable-next-line no-multi-assign // eslint-disable-next-line no-multi-assign
const listeners = const listeners =
pathToListeners[path] || (pathToListeners[path] = new Set()) 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) listeners.delete(l)
// @ts-expect-error
mapListeners.delete(l)
} }
}, },
on(cb) { on(cb) {

View file

@ -25,6 +25,12 @@ namespace Smith {
type: 'on' type: 'on'
} }
export interface SmithMsgLoad {
id: string
path: string
type: 'load'
}
export interface SmithMsgMapOn { export interface SmithMsgMapOn {
path: string path: string
type: 'map.on' type: 'map.on'
@ -41,6 +47,7 @@ namespace Smith {
| SmithMsgInit | SmithMsgInit
| SmithMsgAuth | SmithMsgAuth
| SmithMsgOn | SmithMsgOn
| SmithMsgLoad
| SmithMsgMapOn | SmithMsgMapOn
| SmithMsgPut | SmithMsgPut
| BatchSmithMsg | BatchSmithMsg
@ -65,6 +72,13 @@ namespace Smith {
type: 'map.on' type: 'map.on'
} }
export interface GunMsgLoad {
id: string
data: GunT.LoadListenerData
key: string
type: 'load'
}
export interface GunMsgPut { export interface GunMsgPut {
ack: GunT.Ack ack: GunT.Ack
id: string id: string
@ -72,5 +86,10 @@ namespace Smith {
type: 'put' type: 'put'
} }
export type GunMsg = GunMsgAuth | GunMsgOn | GunMsgMapOn | GunMsgPut export type GunMsg =
| GunMsgAuth
| GunMsgOn
| GunMsgMapOn
| GunMsgLoad
| GunMsgPut
} }