export class BroadcastSync {
    constructor(name, logger = undefined) {
        this.name = name;
        this.logger = logger;
        this.channel = new BroadcastChannel(this.name);
    }
    /** @internal **/
    listen(doc) {
        doc.on('Update', e => {
            if (e.caller == this)
                return;
            this.channel.postMessage({
                type: e.updateType === "message" ? "update" : "state",
                senderID: doc.replicaID,
                data: e.update,
                clock: doc.vectorClock()
            });
            this.logger?.('send', e.updateType === "message" ? "update" : "state", doc.replicaID);
            this.logger?.(doc.vectorClock(), e.caller);
        });
        this.channel.postMessage({
            type: "getState",
            senderID: doc.replicaID,
            clock: doc.vectorClock(),
            data: doc.save()
        });
        this.logger?.('init bc', doc.replicaID);
        this.logger?.(doc.vectorClock());
        this.channel.addEventListener('message', (e) => this.onMessage(doc, e.data));
    }
    onMessage(doc, data) {
        switch (data.type) {
            case "getState":
                this.channel.postMessage({
                    type: 'state',
                    targetID: data.senderID,
                    senderID: doc.replicaID,
                    clock: doc.vectorClock(),
                    data: doc.save()
                });
                data.data && doc.load(data.data, this);
                this.logger?.('get state from', data.senderID, data.clock);
                this.logger?.(doc.vectorClock());
                return;
            case "state":
                if (data.targetID && data.targetID !== doc.replicaID)
                    return;
                doc.load(data.data, this);
                this.logger?.('get state from', data.senderID, data.clock);
                this.logger?.(doc.vectorClock());
                return;
            case "update":
                if (data.targetID && data.targetID !== doc.replicaID)
                    return;
                doc.receive(data.data, this);
                this.logger?.('get update from', data.senderID, data.clock);
                this.logger?.(doc.vectorClock());
                return;
        }
    }
}
