Packages

LiveView-like experience for JSON endpoints

Current section

Files

Jump to
live_data priv static live_data_client.js
Raw

priv/static/live_data_client.js

var OpKind;
(function(OpKind1) {
OpKind1[OpKind1["Render"] = 0] = "Render";
OpKind1[OpKind1["SetFragment"] = 1] = "SetFragment";
OpKind1[OpKind1["SetFragmentRootTemplate"] = 2] = "SetFragmentRootTemplate";
OpKind1[OpKind1["PatchFragment"] = 3] = "PatchFragment";
OpKind1[OpKind1["SetTemplate"] = 4] = "SetTemplate";
OpKind1[OpKind1["Reset"] = 5] = "Reset";
})(OpKind || (OpKind = {
}));
class JSONEncoding {
handleMessage(ops) {
let rendered = false;
ops.forEach((op)=>{
let kind = op[0];
switch(kind){
case OpKind.Render:
this.out = this.renderFragment(op[1]);
rendered = true;
break;
case OpKind.SetFragment:
this.fragments[op[1]] = op[2];
break;
case OpKind.SetFragmentRootTemplate:
this.fragments[op[1]] = [
"$t",
op[2]
].concat(op.slice(3));
break;
case OpKind.PatchFragment:
throw "unimpl";
case OpKind.SetTemplate:
this.templates[op[1]] = op[2];
break;
}
});
return rendered;
}
renderFragment(fragmentId) {
let body = this.fragments[fragmentId];
return this.renderBody(body);
}
renderTemplate(templateId, slots) {
let body = this.templates[templateId];
return this.renderBody(body, slots);
}
renderBody(body, templateSlots = null) {
if (body === null) return null;
if (Array.isArray(body)) {
if (body[0] == "$r") return this.renderFragment(body[1]);
else if (body[0] == "$t") {
let innerSlots = body.slice(2).map((slot)=>this.renderBody(slot, templateSlots)
);
return this.renderTemplate(body[1], innerSlots);
} else if (body[0] == "$s") return templateSlots[body[1]];
else if (body[0] == "$e") return body[1];
else return body.map((item)=>this.renderBody(item, templateSlots)
);
}
if (typeof body == 'object') {
let out = {
};
for (const [key, val] of Object.entries(body))out[key] = this.renderBody(val, templateSlots);
return out;
}
if (typeof body == 'string') return body;
if (typeof body == 'number') return body;
if (body === true || body == false) return body;
console.log(body);
throw "unimpl";
}
constructor(){
this.fragments = {
};
this.templates = {
};
this.out = null;
}
}
console.log("yay");
class Socket1 {
connect() {
this.socket.connect();
}
dataView(route, initialParams, opts = {
}) {
return new LiveData1(route, initialParams, opts, this);
}
nextDvCounter() {
this.dvCounter += 1;
return this.dvCounter;
}
constructor(url, phxSocket, opts = {
}){
this.dvCounter = 0;
this.socket = new phxSocket(url, opts);
this.opts = opts;
}
}
class EventBus {
add(listener) {
let id = this.nextId;
this.nextId += 1;
this.listeners.set(id, listener);
return id;
}
remove(id) {
return this.listeners.delete(id);
}
call(...args) {
this.listeners.forEach((listener)=>listener(...args)
);
}
constructor(){
this.nextId = 0;
this.listeners = new Map();
}
}
var RejoinPolicy1;
(function(RejoinPolicy1) {
RejoinPolicy1[RejoinPolicy1["Once"] = 0] = "Once";
RejoinPolicy1[RejoinPolicy1["Persist"] = 1] = "Persist";
})(RejoinPolicy1 || (RejoinPolicy1 = {
}));
var LiveDataState;
(function(LiveDataState1) {
LiveDataState1["ChannelJoining"] = "channel_joining";
LiveDataState1["Joining"] = "joining";
LiveDataState1["Active"] = "active";
LiveDataState1["Terminal"] = "terminal";
})(LiveDataState || (LiveDataState = {
}));
class LiveData1 {
set state(state) {
this._state = state;
this.onState.call(this._state);
}
get state() {
return this._state;
}
get data() {
return this.encoding.out;
}
joinChannel() {
this.joinPush = this.channel.join();
this.joinPush.receive("ok", ({ messages })=>{
this.state = LiveDataState.ChannelJoining;
});
this.joinPush.receive("error", ({ reason })=>{
this.state = LiveDataState.Terminal;
});
this.joinPush.receive("timeout", ()=>{
this.state = LiveDataState.ChannelJoining;
});
}
pushEvent(data) {
return this.channel.push("e", {
d: data
});
}
constructor(route, initialParams, opts1, socket){
this.onState = new EventBus();
this._state = LiveDataState.ChannelJoining;
this.onData = new EventBus();
this.rejoinPolicy = opts1["rejoinPolicy"] || RejoinPolicy1.Persist;
this.socket = socket;
this.encoding = new JSONEncoding();
let topic = "dv:c:" + this.socket.nextDvCounter();
this.channel = this.socket.socket.channel(topic, {
"r": [
route,
initialParams
]
});
this.channel.onError(()=>{
});
this.channel.onClose(()=>{
});
this.channel.on("o", (payload)=>{
console.log(payload);
let rendered = this.encoding.handleMessage(payload["o"]);
if (this.state == LiveDataState.ChannelJoining) this.state = LiveDataState.Active;
if (rendered) this.onData.call(this.data);
});
this.joinChannel();
}
}
export { Socket1 as Socket };
export { RejoinPolicy1 as RejoinPolicy, };
export { LiveData1 as LiveData };