Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@instantdb/core

Package Overview
Dependencies
Maintainers
2
Versions
205
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@instantdb/core - npm Package Compare versions

Comparing version 0.5.2 to 0.5.3

92

dist/instaql.js

@@ -32,4 +32,4 @@ "use strict";

// -----------------
function makeVar(x) {
return `?${x}`;
function makeVar(x, level) {
return `?${x}-${level}`;
}

@@ -44,4 +44,4 @@ function ignoredAttr(attrs, id) {

// -----------------
function defaultWhere(store, ns) {
return [eidWhere(store, ns), attrWhere(ns)];
function defaultWhere(store, etype, level) {
return [eidWhere(store, etype, level), attrWhere(etype, level)];
}

@@ -55,7 +55,7 @@ function idAttr(store, ns) {

}
function eidWhere(store, ns) {
return [makeVar(ns), idAttr(store, ns).id, makeVar(ns)];
function eidWhere(store, etype, level) {
return [makeVar(etype, level), idAttr(store, etype).id, makeVar(etype, level)];
}
function attrWhere(ns) {
return [makeVar(ns), ATTR_VAR, VAL_VAR];
function attrWhere(etype, level) {
return [makeVar(etype, level), ATTR_VAR, VAL_VAR];
}

@@ -65,3 +65,3 @@ function replaceInAttrPat(attrPat, needle, v) {

}
function refAttrPat(store, etype, label) {
function refAttrPat(store, etype, level, label) {
const fwdAttr = getAttrByFwdIdentName(store.attrs, etype, label);

@@ -78,7 +78,10 @@ const revAttr = getAttrByReverseIdentName(store.attrs, etype, label);

const [_r, revEtype] = attr["reverse-identity"];
const attrPat = [makeVar(fwdEtype), attr.id, makeVar(revEtype)];
const nextLevel = level + 1;
const attrPat = fwdAttr
? [makeVar(fwdEtype, level), attr.id, makeVar(revEtype, nextLevel)]
: [makeVar(fwdEtype, nextLevel), attr.id, makeVar(revEtype, level)];
const nextEtype = fwdAttr ? revEtype : fwdEtype;
return [nextEtype, attrPat];
return [nextEtype, nextLevel, attrPat];
}
function valueAttrPat(store, valueEtype, valueLabel, v) {
function valueAttrPat(store, valueEtype, valueLevel, valueLabel, v) {
const attr = getAttrByFwdIdentName(store.attrs, valueEtype, valueLabel);

@@ -88,40 +91,40 @@ if (!attr) {

}
return [makeVar(valueEtype), attr.id, v];
return [makeVar(valueEtype, valueLevel), attr.id, v];
}
function refAttrPats(store, etype, refsPath) {
const [lastEtype, attrPats] = refsPath.reduce((acc, label) => {
const [etype, attrPats] = acc;
const [nextEtype, attrPat] = refAttrPat(store, etype, label);
return [nextEtype, [...attrPats, attrPat]];
}, [etype, []]);
return [lastEtype, attrPats];
function refAttrPats(store, etype, level, refsPath) {
const [lastEtype, lastLevel, attrPats] = refsPath.reduce((acc, label) => {
const [etype, level, attrPats] = acc;
const [nextEtype, nextLevel, attrPat] = refAttrPat(store, etype, level, label);
return [nextEtype, nextLevel, [...attrPats, attrPat]];
}, [etype, level, []]);
return [lastEtype, lastLevel, attrPats];
}
function whereCondAttrPats(store, etype, path, v) {
function whereCondAttrPats(store, etype, level, path, v) {
const refsPath = path.slice(0, path.length - 1);
const valueLabel = path[path.length - 1];
const [lastEtype, refPats] = refAttrPats(store, etype, refsPath);
const valuePat = valueAttrPat(store, lastEtype, valueLabel, v);
const [lastEtype, lastLevel, refPats] = refAttrPats(store, etype, level, refsPath);
const valuePat = valueAttrPat(store, lastEtype, lastLevel, valueLabel, v);
return refPats.concat([valuePat]);
}
function makeWhere(store, ns, where) {
function makeWhere(store, etype, level, where) {
if (!where) {
return defaultWhere(store, ns);
return defaultWhere(store, etype, level);
}
const parsedWhere = Object.entries(where).flatMap(([k, v]) => {
const path = k.split(".");
return whereCondAttrPats(store, ns, path, v);
return whereCondAttrPats(store, etype, level, path, v);
});
return parsedWhere.concat(defaultWhere(store, ns));
return parsedWhere.concat(defaultWhere(store, etype, level));
}
// Find
// -----------------
function makeFind(ns) {
return [makeVar(ns), ATTR_VAR, VAL_VAR];
function makeFind(etype, level) {
return [makeVar(etype, level), ATTR_VAR, VAL_VAR];
}
// Relations
// -----------------
function makeJoin(store, etype, label, eid) {
const [nextEtype, pat] = refAttrPat(store, etype, label);
const actualized = replaceInAttrPat(pat, makeVar(etype), eid);
return [nextEtype, actualized];
function makeJoin(store, etype, level, label, eid) {
const [nextEtype, nextLevel, pat] = refAttrPat(store, etype, level, label);
const actualized = replaceInAttrPat(pat, makeVar(etype, level), eid);
return [nextEtype, nextLevel, actualized];
}

@@ -145,9 +148,9 @@ function withJoin(where, join) {

}
function queryParents(store, { etype, form, join }) {
function queryParents(store, { etype, level, form, join }) {
var _a;
const where = withJoin(makeWhere(store, etype, (_a = form.$) === null || _a === void 0 ? void 0 : _a.where), join);
const find = makeFind(etype);
const where = withJoin(makeWhere(store, etype, level, (_a = form.$) === null || _a === void 0 ? void 0 : _a.where), join);
const find = makeFind(etype, level);
return runDatalog(store, { where, find });
}
function guaredQueryParents(store, opts) {
function guardedQueryParents(store, opts) {
try {

@@ -163,3 +166,3 @@ return queryParents(store, opts);

}
function extendParents(store, { etype, form }, parents) {
function extendParents(store, { etype, level, form }, parents) {
const children = Object.keys(form).filter((c) => c !== "$");

@@ -176,4 +179,9 @@ if (!children.length) {

try {
const [nextEtype, join] = makeJoin(store, etype, label, eid);
const child = queryOne(store, { etype: nextEtype, form: form[label], join });
const [nextEtype, nextLevel, join] = makeJoin(store, etype, level, label, eid);
const child = queryOne(store, {
etype: nextEtype,
level: nextLevel,
form: form[label],
join
});
return { [label]: child };

@@ -194,3 +202,3 @@ }

function queryOne(store, opts) {
const parents = guaredQueryParents(store, opts);
const parents = guardedQueryParents(store, opts);
return extendParents(store, opts, parents);

@@ -200,3 +208,3 @@ }

return Object.keys(q).reduce((res, k) => {
res[k] = queryOne(store, { etype: k, form: q[k] });
res[k] = queryOne(store, { etype: k, form: q[k], level: 0 });
return res;

@@ -203,0 +211,0 @@ }, {});

@@ -30,4 +30,4 @@ import { query as datalogQuery } from "./datalog";

// -----------------
function makeVar(x) {
return `?${x}`;
function makeVar(x, level) {
return `?${x}-${level}`;
}

@@ -42,4 +42,4 @@ function ignoredAttr(attrs, id) {

// -----------------
function defaultWhere(store, ns) {
return [eidWhere(store, ns), attrWhere(ns)];
function defaultWhere(store, etype, level) {
return [eidWhere(store, etype, level), attrWhere(etype, level)];
}

@@ -53,7 +53,7 @@ function idAttr(store, ns) {

}
function eidWhere(store, ns) {
return [makeVar(ns), idAttr(store, ns).id, makeVar(ns)];
function eidWhere(store, etype, level) {
return [makeVar(etype, level), idAttr(store, etype).id, makeVar(etype, level)];
}
function attrWhere(ns) {
return [makeVar(ns), ATTR_VAR, VAL_VAR];
function attrWhere(etype, level) {
return [makeVar(etype, level), ATTR_VAR, VAL_VAR];
}

@@ -63,3 +63,3 @@ function replaceInAttrPat(attrPat, needle, v) {

}
function refAttrPat(store, etype, label) {
function refAttrPat(store, etype, level, label) {
const fwdAttr = getAttrByFwdIdentName(store.attrs, etype, label);

@@ -76,7 +76,10 @@ const revAttr = getAttrByReverseIdentName(store.attrs, etype, label);

const [_r, revEtype] = attr["reverse-identity"];
const attrPat = [makeVar(fwdEtype), attr.id, makeVar(revEtype)];
const nextLevel = level + 1;
const attrPat = fwdAttr
? [makeVar(fwdEtype, level), attr.id, makeVar(revEtype, nextLevel)]
: [makeVar(fwdEtype, nextLevel), attr.id, makeVar(revEtype, level)];
const nextEtype = fwdAttr ? revEtype : fwdEtype;
return [nextEtype, attrPat];
return [nextEtype, nextLevel, attrPat];
}
function valueAttrPat(store, valueEtype, valueLabel, v) {
function valueAttrPat(store, valueEtype, valueLevel, valueLabel, v) {
const attr = getAttrByFwdIdentName(store.attrs, valueEtype, valueLabel);

@@ -86,40 +89,40 @@ if (!attr) {

}
return [makeVar(valueEtype), attr.id, v];
return [makeVar(valueEtype, valueLevel), attr.id, v];
}
function refAttrPats(store, etype, refsPath) {
const [lastEtype, attrPats] = refsPath.reduce((acc, label) => {
const [etype, attrPats] = acc;
const [nextEtype, attrPat] = refAttrPat(store, etype, label);
return [nextEtype, [...attrPats, attrPat]];
}, [etype, []]);
return [lastEtype, attrPats];
function refAttrPats(store, etype, level, refsPath) {
const [lastEtype, lastLevel, attrPats] = refsPath.reduce((acc, label) => {
const [etype, level, attrPats] = acc;
const [nextEtype, nextLevel, attrPat] = refAttrPat(store, etype, level, label);
return [nextEtype, nextLevel, [...attrPats, attrPat]];
}, [etype, level, []]);
return [lastEtype, lastLevel, attrPats];
}
function whereCondAttrPats(store, etype, path, v) {
function whereCondAttrPats(store, etype, level, path, v) {
const refsPath = path.slice(0, path.length - 1);
const valueLabel = path[path.length - 1];
const [lastEtype, refPats] = refAttrPats(store, etype, refsPath);
const valuePat = valueAttrPat(store, lastEtype, valueLabel, v);
const [lastEtype, lastLevel, refPats] = refAttrPats(store, etype, level, refsPath);
const valuePat = valueAttrPat(store, lastEtype, lastLevel, valueLabel, v);
return refPats.concat([valuePat]);
}
function makeWhere(store, ns, where) {
function makeWhere(store, etype, level, where) {
if (!where) {
return defaultWhere(store, ns);
return defaultWhere(store, etype, level);
}
const parsedWhere = Object.entries(where).flatMap(([k, v]) => {
const path = k.split(".");
return whereCondAttrPats(store, ns, path, v);
return whereCondAttrPats(store, etype, level, path, v);
});
return parsedWhere.concat(defaultWhere(store, ns));
return parsedWhere.concat(defaultWhere(store, etype, level));
}
// Find
// -----------------
function makeFind(ns) {
return [makeVar(ns), ATTR_VAR, VAL_VAR];
function makeFind(etype, level) {
return [makeVar(etype, level), ATTR_VAR, VAL_VAR];
}
// Relations
// -----------------
function makeJoin(store, etype, label, eid) {
const [nextEtype, pat] = refAttrPat(store, etype, label);
const actualized = replaceInAttrPat(pat, makeVar(etype), eid);
return [nextEtype, actualized];
function makeJoin(store, etype, level, label, eid) {
const [nextEtype, nextLevel, pat] = refAttrPat(store, etype, level, label);
const actualized = replaceInAttrPat(pat, makeVar(etype, level), eid);
return [nextEtype, nextLevel, actualized];
}

@@ -143,9 +146,9 @@ function withJoin(where, join) {

}
function queryParents(store, { etype, form, join }) {
function queryParents(store, { etype, level, form, join }) {
var _a;
const where = withJoin(makeWhere(store, etype, (_a = form.$) === null || _a === void 0 ? void 0 : _a.where), join);
const find = makeFind(etype);
const where = withJoin(makeWhere(store, etype, level, (_a = form.$) === null || _a === void 0 ? void 0 : _a.where), join);
const find = makeFind(etype, level);
return runDatalog(store, { where, find });
}
function guaredQueryParents(store, opts) {
function guardedQueryParents(store, opts) {
try {

@@ -161,3 +164,3 @@ return queryParents(store, opts);

}
function extendParents(store, { etype, form }, parents) {
function extendParents(store, { etype, level, form }, parents) {
const children = Object.keys(form).filter((c) => c !== "$");

@@ -174,4 +177,9 @@ if (!children.length) {

try {
const [nextEtype, join] = makeJoin(store, etype, label, eid);
const child = queryOne(store, { etype: nextEtype, form: form[label], join });
const [nextEtype, nextLevel, join] = makeJoin(store, etype, level, label, eid);
const child = queryOne(store, {
etype: nextEtype,
level: nextLevel,
form: form[label],
join
});
return { [label]: child };

@@ -192,3 +200,3 @@ }

function queryOne(store, opts) {
const parents = guaredQueryParents(store, opts);
const parents = guardedQueryParents(store, opts);
return extendParents(store, opts, parents);

@@ -198,3 +206,3 @@ }

return Object.keys(q).reduce((res, k) => {
res[k] = queryOne(store, { etype: k, form: q[k] });
res[k] = queryOne(store, { etype: k, form: q[k], level: 0 });
return res;

@@ -201,0 +209,0 @@ }, {});

@@ -19,3 +19,2 @@ export default class ReactiveDB {

* effects:
* - Send add query for querySubs in storage but not in memory
* - We notify all queryCbs because results may been added during merge

@@ -56,2 +55,3 @@ */

notifyOne: (hash: any) => void;
notifyQueryError: (hash: any, msg: any) => void;
/** Re-compute all subscriptions */

@@ -58,0 +58,0 @@ notifyAll(): void;

@@ -56,2 +56,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

}
// PersistedObjects save data outside of memory
// When we load a persisted object, it's possible we call `set`
// before we finish loading. To address we handle set in two ways:
//
// 1. Before load
// We simply update currentValue in memory
//
// 2. After load
// We update currentValue in memory and in storage
//
// Each PersistedObject provides it's own `onMerge`
// function to handle the merge of data from storage and memory
// on load
class PersistedObject {

@@ -105,3 +118,2 @@ constructor(persister, key, defaultValue, onMerge, toJSON = (x) => {

* effects:
* - Send add query for querySubs in storage but not in memory
* - We notify all queryCbs because results may been added during merge

@@ -140,8 +152,2 @@ */

this.querySubs.set((_) => ret);
// Since these subs have not been subscribed before,
// we nede to send an add-query message to the server
storageKsToAdd.forEach((k) => {
const { q, eventId } = ret[k];
this._send(eventId, { op: "add-query", q });
});
this.notifyAll();

@@ -172,2 +178,6 @@ };

};
this.notifyQueryError = (hash, msg) => {
const cbs = this.queryCbs[hash] || [];
cbs.forEach((cb) => cb({ error: msg }));
};
this._wsOnOpen = () => {

@@ -254,2 +264,3 @@ log.info("[socket] connected");

_handleReceive(msg) {
var _a;
switch (msg.op) {

@@ -315,3 +326,4 @@ case "init-ok":

// (XXX): Error handling is spaghetti right now.
const { "client-event-id": errorEventId, q: errorQ } = msg;
const errorQ = msg.q || ((_a = msg["original-event"]) === null || _a === void 0 ? void 0 : _a.q);
const { "client-event-id": errorEventId } = msg;
const errorObj = Object.assign({}, msg);

@@ -332,3 +344,3 @@ delete errorObj.message;

}
if (errorQ && msg.status === 400) {
if (errorQ) {
// This is a hack.

@@ -344,2 +356,3 @@ // Imagine a user writes a malformed query.

});
this.notifyQueryError(weakHash(errorQ), { message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa." });
}

@@ -375,2 +388,7 @@ break;

this.queryCbs[hash].push(cb);
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
this._send(eventId, { op: "add-query", q });
const prevResult = (_b = (_a = this.querySubs.currentValue) === null || _a === void 0 ? void 0 : _a[hash]) === null || _b === void 0 ? void 0 : _b.result;

@@ -380,7 +398,2 @@ if (prevResult) {

}
this._send(eventId, { op: "add-query", q });
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
return () => {

@@ -511,3 +524,9 @@ this.queryCbs[hash] = this.queryCbs[hash].filter((x) => x !== cb);

_flushPendingMessages() {
Object.values(this.querySubs.currentValue).forEach(({ eventId, q }) => {
const subs = Object.keys(this.queryCbs).map((hash) => {
return this.querySubs.currentValue[hash];
});
// Note: we should not have any nulls in subs, but we're
// doing this defensively just in case.
const safeSubs = subs.filter(x => x);
safeSubs.forEach(({ eventId, q }) => {
this._send(eventId, { op: "add-query", q });

@@ -597,2 +616,3 @@ });

yield this.setCurrentUser(newUser);
this.querySubs.set((_) => ({}));
this._reconnectTimeoutMs = 0;

@@ -599,0 +619,0 @@ this._ws.close();

@@ -19,3 +19,2 @@ export default class ReactiveDB {

* effects:
* - Send add query for querySubs in storage but not in memory
* - We notify all queryCbs because results may been added during merge

@@ -56,2 +55,3 @@ */

notifyOne: (hash: any) => void;
notifyQueryError: (hash: any, msg: any) => void;
/** Re-compute all subscriptions */

@@ -58,0 +58,0 @@ notifyAll(): void;

@@ -84,2 +84,15 @@ "use strict";

}
// PersistedObjects save data outside of memory
// When we load a persisted object, it's possible we call `set`
// before we finish loading. To address we handle set in two ways:
//
// 1. Before load
// We simply update currentValue in memory
//
// 2. After load
// We update currentValue in memory and in storage
//
// Each PersistedObject provides it's own `onMerge`
// function to handle the merge of data from storage and memory
// on load
class PersistedObject {

@@ -133,3 +146,2 @@ constructor(persister, key, defaultValue, onMerge, toJSON = (x) => {

* effects:
* - Send add query for querySubs in storage but not in memory
* - We notify all queryCbs because results may been added during merge

@@ -168,8 +180,2 @@ */

this.querySubs.set((_) => ret);
// Since these subs have not been subscribed before,
// we nede to send an add-query message to the server
storageKsToAdd.forEach((k) => {
const { q, eventId } = ret[k];
this._send(eventId, { op: "add-query", q });
});
this.notifyAll();

@@ -200,2 +206,6 @@ };

};
this.notifyQueryError = (hash, msg) => {
const cbs = this.queryCbs[hash] || [];
cbs.forEach((cb) => cb({ error: msg }));
};
this._wsOnOpen = () => {

@@ -282,2 +292,3 @@ log_1.default.info("[socket] connected");

_handleReceive(msg) {
var _a;
switch (msg.op) {

@@ -343,3 +354,4 @@ case "init-ok":

// (XXX): Error handling is spaghetti right now.
const { "client-event-id": errorEventId, q: errorQ } = msg;
const errorQ = msg.q || ((_a = msg["original-event"]) === null || _a === void 0 ? void 0 : _a.q);
const { "client-event-id": errorEventId } = msg;
const errorObj = Object.assign({}, msg);

@@ -360,3 +372,3 @@ delete errorObj.message;

}
if (errorQ && msg.status === 400) {
if (errorQ) {
// This is a hack.

@@ -372,2 +384,3 @@ // Imagine a user writes a malformed query.

});
this.notifyQueryError((0, weakHash_1.default)(errorQ), { message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa." });
}

@@ -403,2 +416,7 @@ break;

this.queryCbs[hash].push(cb);
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
this._send(eventId, { op: "add-query", q });
const prevResult = (_b = (_a = this.querySubs.currentValue) === null || _a === void 0 ? void 0 : _a[hash]) === null || _b === void 0 ? void 0 : _b.result;

@@ -408,7 +426,2 @@ if (prevResult) {

}
this._send(eventId, { op: "add-query", q });
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
return () => {

@@ -539,3 +552,9 @@ this.queryCbs[hash] = this.queryCbs[hash].filter((x) => x !== cb);

_flushPendingMessages() {
Object.values(this.querySubs.currentValue).forEach(({ eventId, q }) => {
const subs = Object.keys(this.queryCbs).map((hash) => {
return this.querySubs.currentValue[hash];
});
// Note: we should not have any nulls in subs, but we're
// doing this defensively just in case.
const safeSubs = subs.filter(x => x);
safeSubs.forEach(({ eventId, q }) => {
this._send(eventId, { op: "add-query", q });

@@ -625,2 +644,3 @@ });

yield this.setCurrentUser(newUser);
this.querySubs.set((_) => ({}));
this._reconnectTimeoutMs = 0;

@@ -627,0 +647,0 @@ this._ws.close();

{
"name": "@instantdb/core",
"version": "0.5.2",
"version": "0.5.3",
"description": "Instant's core local abstraction",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -36,4 +36,4 @@ import { query as datalogQuery } from "./datalog";

function makeVar(x) {
return `?${x}`;
function makeVar(x, level) {
return `?${x}-${level}`;
}

@@ -53,4 +53,4 @@

function defaultWhere(store, ns) {
return [eidWhere(store, ns), attrWhere(ns)];
function defaultWhere(store, etype, level) {
return [eidWhere(store, etype, level), attrWhere(etype, level)];
}

@@ -66,8 +66,8 @@

function eidWhere(store, ns) {
return [makeVar(ns), idAttr(store, ns).id, makeVar(ns)];
function eidWhere(store, etype, level) {
return [makeVar(etype, level), idAttr(store, etype).id, makeVar(etype, level)];
}
function attrWhere(ns) {
return [makeVar(ns), ATTR_VAR, VAL_VAR];
function attrWhere(etype, level) {
return [makeVar(etype, level), ATTR_VAR, VAL_VAR];
}

@@ -79,3 +79,3 @@

function refAttrPat(store, etype, label) {
function refAttrPat(store, etype, level, label) {
const fwdAttr = getAttrByFwdIdentName(store.attrs, etype, label);

@@ -95,9 +95,13 @@ const revAttr = getAttrByReverseIdentName(store.attrs, etype, label);

const [_r, revEtype] = attr["reverse-identity"];
const attrPat = [makeVar(fwdEtype), attr.id, makeVar(revEtype)];
const nextLevel = level + 1;
const attrPat = fwdAttr
? [makeVar(fwdEtype, level), attr.id, makeVar(revEtype, nextLevel)]
: [makeVar(fwdEtype, nextLevel), attr.id, makeVar(revEtype, level)];
const nextEtype = fwdAttr ? revEtype : fwdEtype;
return [nextEtype, attrPat];
return [nextEtype, nextLevel, attrPat];
}
function valueAttrPat(store, valueEtype, valueLabel, v) {
function valueAttrPat(store, valueEtype, valueLevel, valueLabel, v) {
const attr = getAttrByFwdIdentName(store.attrs, valueEtype, valueLabel);

@@ -111,23 +115,23 @@

return [makeVar(valueEtype), attr.id, v];
return [makeVar(valueEtype, valueLevel), attr.id, v];
}
function refAttrPats(store, etype, refsPath) {
const [lastEtype, attrPats] = refsPath.reduce(
function refAttrPats(store, etype, level, refsPath) {
const [lastEtype, lastLevel, attrPats] = refsPath.reduce(
(acc, label) => {
const [etype, attrPats] = acc;
const [nextEtype, attrPat] = refAttrPat(store, etype, label);
return [nextEtype, [...attrPats, attrPat]];
const [etype, level, attrPats] = acc;
const [nextEtype, nextLevel, attrPat] = refAttrPat(store, etype, level, label);
return [nextEtype, nextLevel, [...attrPats, attrPat]];
},
[etype, []],
[etype, level, []],
);
return [lastEtype, attrPats];
return [lastEtype, lastLevel, attrPats];
}
function whereCondAttrPats(store, etype, path, v) {
function whereCondAttrPats(store, etype, level, path, v) {
const refsPath = path.slice(0, path.length - 1);
const valueLabel = path[path.length - 1];
const [lastEtype, refPats] = refAttrPats(store, etype, refsPath);
const valuePat = valueAttrPat(store, lastEtype, valueLabel, v);
const [lastEtype, lastLevel, refPats] = refAttrPats(store, etype, level, refsPath);
const valuePat = valueAttrPat(store, lastEtype, lastLevel, valueLabel, v);

@@ -137,11 +141,11 @@ return refPats.concat([valuePat]);

function makeWhere(store, ns, where) {
function makeWhere(store, etype, level, where) {
if (!where) {
return defaultWhere(store, ns);
return defaultWhere(store, etype, level);
}
const parsedWhere = Object.entries(where).flatMap(([k, v]) => {
const path = k.split(".");
return whereCondAttrPats(store, ns, path, v);
return whereCondAttrPats(store, etype, level, path, v);
});
return parsedWhere.concat(defaultWhere(store, ns));
return parsedWhere.concat(defaultWhere(store, etype, level));
}

@@ -152,4 +156,4 @@

function makeFind(ns) {
return [makeVar(ns), ATTR_VAR, VAL_VAR];
function makeFind(etype, level) {
return [makeVar(etype, level), ATTR_VAR, VAL_VAR];
}

@@ -160,6 +164,6 @@

function makeJoin(store, etype, label, eid) {
const [nextEtype, pat] = refAttrPat(store, etype, label);
const actualized = replaceInAttrPat(pat, makeVar(etype), eid);
return [nextEtype, actualized];
function makeJoin(store, etype, level, label, eid) {
const [nextEtype, nextLevel, pat] = refAttrPat(store, etype, level, label);
const actualized = replaceInAttrPat(pat, makeVar(etype, level), eid);
return [nextEtype, nextLevel, actualized];
}

@@ -187,9 +191,9 @@

function queryParents(store, { etype, form, join }) {
const where = withJoin(makeWhere(store, etype, form.$?.where), join);
const find = makeFind(etype);
function queryParents(store, { etype, level, form, join }) {
const where = withJoin(makeWhere(store, etype, level, form.$?.where), join);
const find = makeFind(etype, level);
return runDatalog(store, { where, find });
}
function guaredQueryParents(store, opts) {
function guardedQueryParents(store, opts) {
try {

@@ -205,3 +209,3 @@ return queryParents(store, opts);

function extendParents(store, { etype, form }, parents) {
function extendParents(store, { etype, level, form }, parents) {
const children = Object.keys(form).filter((c) => c !== "$");

@@ -219,4 +223,9 @@ if (!children.length) {

try {
const [nextEtype, join] = makeJoin(store, etype, label, eid);
const child = queryOne(store, { etype: nextEtype, form: form[label], join });
const [nextEtype, nextLevel, join] = makeJoin(store, etype, level, label, eid);
const child = queryOne(store, {
etype: nextEtype,
level: nextLevel,
form: form[label],
join
});
return { [label]: child };

@@ -238,3 +247,3 @@ } catch (e) {

function queryOne(store, opts) {
const parents = guaredQueryParents(store, opts);
const parents = guardedQueryParents(store, opts);
return extendParents(store, opts, parents);

@@ -245,5 +254,5 @@ }

return Object.keys(q).reduce((res, k) => {
res[k] = queryOne(store, { etype: k, form: q[k] });
res[k] = queryOne(store, { etype: k, form: q[k], level: 0 });
return res;
}, {});
}

@@ -50,2 +50,15 @@ import log from "./utils/log";

// PersistedObjects save data outside of memory
// When we load a persisted object, it's possible we call `set`
// before we finish loading. To address we handle set in two ways:
//
// 1. Before load
// We simply update currentValue in memory
//
// 2. After load
// We update currentValue in memory and in storage
//
// Each PersistedObject provides it's own `onMerge`
// function to handle the merge of data from storage and memory
// on load
class PersistedObject {

@@ -169,3 +182,2 @@ constructor(

* effects:
* - Send add query for querySubs in storage but not in memory
* - We notify all queryCbs because results may been added during merge

@@ -208,9 +220,2 @@ */

// Since these subs have not been subscribed before,
// we nede to send an add-query message to the server
storageKsToAdd.forEach((k) => {
const { q, eventId } = ret[k];
this._send(eventId, { op: "add-query", q });
});
this.notifyAll();

@@ -318,3 +323,4 @@ };

// (XXX): Error handling is spaghetti right now.
const { "client-event-id": errorEventId, q: errorQ } = msg;
const errorQ = msg.q || msg["original-event"]?.q;
const { "client-event-id": errorEventId } = msg;
const errorObj = { ...msg };

@@ -339,3 +345,3 @@ delete errorObj.message;

}
if (errorQ && msg.status === 400) {
if (errorQ) {
// This is a hack.

@@ -351,2 +357,3 @@ // Imagine a user writes a malformed query.

});
this.notifyQueryError(weakHash(errorQ), { message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa." });
}

@@ -382,4 +389,12 @@ break;

const hash = weakHash(q);
this.queryCbs[hash] = this.queryCbs[hash] || [];
this.queryCbs[hash].push(cb);
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
this._send(eventId, { op: "add-query", q });
const prevResult = this.querySubs.currentValue?.[hash]?.result;

@@ -389,7 +404,3 @@ if (prevResult) {

}
this._send(eventId, { op: "add-query", q });
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
return () => {

@@ -501,2 +512,8 @@ this.queryCbs[hash] = this.queryCbs[hash].filter((x) => x !== cb);

notifyQueryError = (hash, msg) => {
const cbs = this.queryCbs[hash] || [];
cbs.forEach((cb) => cb({ error: msg }));
};
/** Re-compute all subscriptions */

@@ -554,3 +571,9 @@ notifyAll() {

_flushPendingMessages() {
Object.values(this.querySubs.currentValue).forEach(({ eventId, q }) => {
const subs = Object.keys(this.queryCbs).map((hash) => {
return this.querySubs.currentValue[hash];
})
// Note: we should not have any nulls in subs, but we're
// doing this defensively just in case.
const safeSubs = subs.filter(x => x);
safeSubs.forEach(({ eventId, q }) => {
this._send(eventId, { op: "add-query", q });

@@ -678,2 +701,3 @@ });

await this.setCurrentUser(newUser);
this.querySubs.set((_) => ({}));
this._reconnectTimeoutMs = 0;

@@ -680,0 +704,0 @@ this._ws.close();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc