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

@instantdb/core

Package Overview
Dependencies
Maintainers
4
Versions
206
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.10.10 to 0.10.11

63

__tests__/src/instaql.test.js

@@ -87,2 +87,21 @@ import { test, expect } from "vitest";

test("Where and", () => {
expect(
query(store, {
users: {
$: {
where: {
and: [
{ "bookshelves.books.title": "The Count of Monte Cristo" },
{ "bookshelves.books.title": "Antifragile" },
],
},
},
},
})
.users.map((x) => x.handle)
.sort(),
).toEqual(["nicolegf", "stopa"]);
});
test.each([

@@ -166,2 +185,23 @@ [

],
[
"with ands in ors",
{
or: [
{
or: [
{
and: [
{ or: [{ handle: "stopa" }, { handle: "joe" }] },
{ email: "stepan.p@gmail.com" },
],
},
],
},
{
handle: "joe",
},
],
},
["joe", "stopa"],
],
])("Where OR %s", (_, whereQuery, expected) => {

@@ -271,2 +311,25 @@ expect(

test("Nested wheres with AND queries", () => {
expect(
query(store, {
users: {
bookshelves: {
books: {},
$: {
where: { and: [{ name: "Short Stories" }, { order: 0 }] },
},
},
$: { where: { handle: "alex" } },
},
})
.users.flatMap((x) => x.bookshelves)
.flatMap((x) => x.books)
.map((x) => x.title),
).toEqual([
"The Paper Menagerie and Other Stories",
"Stories of Your Life and Others",
"Aesop's Fables",
]);
});
test("Deep where", () => {

@@ -273,0 +336,0 @@ expect(

@@ -63,2 +63,7 @@ "use strict";

}
if (pattern.and) {
return pattern.and.patterns.reduce((contexts, patterns) => {
return queryWhere(store, patterns, contexts);
}, contexts);
}
return contexts.flatMap((context) => querySingle(store, pattern, context));

@@ -65,0 +70,0 @@ }

16

dist/instaql.js

@@ -131,2 +131,5 @@ "use strict";

}
function isAndClauses([k, v]) {
return k === "and" && Array.isArray(v);
}
// Creates a makeVar that will namespace symbols for or clauses

@@ -142,9 +145,9 @@ // to prevent conflicts, except for the base etype

}
function parseWhereOrClauses(makeVar, store, etype, level, whereValue) {
function parseWhereClauses(makeVar, clauseType, /* 'or' | 'and' */ store, etype, level, whereValue) {
const patterns = whereValue.map((w, i) => {
const makeOrVar = genMakeVar(makeVar, etype, i);
return parseWhere(makeOrVar, store, etype, level, w);
const makeNamespacedVar = genMakeVar(makeVar, etype, i);
return parseWhere(makeNamespacedVar, store, etype, level, w);
});
const joinSym = makeVar(etype, level);
return { or: { patterns, joinSym } };
return { [clauseType]: { patterns, joinSym } };
}

@@ -154,4 +157,7 @@ function parseWhere(makeVar, store, etype, level, where) {

if (isOrClauses([k, v])) {
return parseWhereOrClauses(makeVar, store, etype, level, v);
return parseWhereClauses(makeVar, "or", store, etype, level, v);
}
if (isAndClauses([k, v])) {
return parseWhereClauses(makeVar, "and", store, etype, level, v);
}
const path = k.split(".");

@@ -158,0 +164,0 @@ return whereCondAttrPats(makeVar, store, etype, level, path, v);

@@ -58,2 +58,7 @@ // 1. patternMatch

}
if (pattern.and) {
return pattern.and.patterns.reduce((contexts, patterns) => {
return queryWhere(store, patterns, contexts);
}, contexts);
}
return contexts.flatMap((context) => querySingle(store, pattern, context));

@@ -60,0 +65,0 @@ }

@@ -129,2 +129,5 @@ import { query as datalogQuery } from "./datalog";

}
function isAndClauses([k, v]) {
return k === "and" && Array.isArray(v);
}
// Creates a makeVar that will namespace symbols for or clauses

@@ -140,9 +143,9 @@ // to prevent conflicts, except for the base etype

}
function parseWhereOrClauses(makeVar, store, etype, level, whereValue) {
function parseWhereClauses(makeVar, clauseType, /* 'or' | 'and' */ store, etype, level, whereValue) {
const patterns = whereValue.map((w, i) => {
const makeOrVar = genMakeVar(makeVar, etype, i);
return parseWhere(makeOrVar, store, etype, level, w);
const makeNamespacedVar = genMakeVar(makeVar, etype, i);
return parseWhere(makeNamespacedVar, store, etype, level, w);
});
const joinSym = makeVar(etype, level);
return { or: { patterns, joinSym } };
return { [clauseType]: { patterns, joinSym } };
}

@@ -152,4 +155,7 @@ function parseWhere(makeVar, store, etype, level, where) {

if (isOrClauses([k, v])) {
return parseWhereOrClauses(makeVar, store, etype, level, v);
return parseWhereClauses(makeVar, "or", store, etype, level, v);
}
if (isAndClauses([k, v])) {
return parseWhereClauses(makeVar, "and", store, etype, level, v);
}
const path = k.split(".");

@@ -156,0 +162,0 @@ return whereCondAttrPats(makeVar, store, etype, level, path, v);

@@ -8,9 +8,10 @@ declare type NonEmpty<T> = {

declare type WhereClauseValue = string | number | boolean | NonEmpty<WhereArgs>;
declare type WhereClauseWithOr = {
or?: BaseWhereClause[] | WhereClauseValue;
};
declare type BaseWhereClause = {
[key: string]: WhereClauseValue;
};
declare type WhereClause = WhereClauseWithOr | (WhereClauseWithOr & BaseWhereClause);
declare type WhereClauseWithCombinaton = {
or?: WhereClause[] | WhereClauseValue;
and?: WhereClause[] | WhereClauseValue;
};
declare type WhereClause = WhereClauseWithCombinaton | (WhereClauseWithCombinaton & BaseWhereClause);
declare type $Option = {

@@ -17,0 +18,0 @@ $?: {

@@ -46,2 +46,12 @@ // Query

});
const t3 = dummyQuery({
users: { $: { where: { and: [{ foo: 1 }] } } },
});
// You can have a field named and
const t4 = dummyQuery({
users: { $: { where: { and: "fieldNamedAnd" } } },
});
const t5 = dummyQuery({
users: { $: { where: { and: [{ or: [{ foo: 1 }] }] } } },
});
// ------------------

@@ -48,0 +58,0 @@ // Bad $ clauses fail

@@ -141,2 +141,3 @@ /**

}>;
_hasCurrentUser(): Promise<boolean>;
changeCurrentUser(newUser: any): Promise<void>;

@@ -143,0 +144,0 @@ updateUser(newUser: any): void;

@@ -677,3 +677,3 @@ // @ts-check

}
// -----
// ----
// Auth

@@ -686,2 +686,3 @@ _replaceUrlAfterOAuth() {

if (url.searchParams.get(OAUTH_REDIRECT_PARAM)) {
const startUrl = url.toString();
url.searchParams.delete(OAUTH_REDIRECT_PARAM);

@@ -697,2 +698,31 @@ url.searchParams.delete("code");

history.replaceState(history.state, "", newPath);
// navigation is part of the HTML spec, but not supported by Safari
// or Firefox yet:
// https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API#browser_compatibility
if (
// @ts-ignore (waiting for ts support)
typeof navigation === "object" &&
// @ts-ignore (waiting for ts support)
typeof navigation.addEventListener === "function" &&
// @ts-ignore (waiting for ts support)
typeof navigation.removeEventListener === "function") {
let ran = false;
// The next.js app router will reset the URL when the router loads.
// This puts it back after the router loads.
const listener = (e) => {
var _a;
if (!ran) {
ran = true;
// @ts-ignore (waiting for ts support)
navigation.removeEventListener("navigate", listener);
if (!e.userInitiated &&
e.navigationType === "replace" &&
((_a = e.destination) === null || _a === void 0 ? void 0 : _a.url) === startUrl) {
history.replaceState(history.state, "", newPath);
}
}
};
// @ts-ignore (waiting for ts support)
navigation.addEventListener("navigate", listener);
}
}

@@ -705,3 +735,3 @@ }

_oauthLoginInit() {
var _a;
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {

@@ -731,3 +761,3 @@ if (typeof window === "undefined" ||

appId: this.config.appId,
code: code,
code,
});

@@ -738,3 +768,10 @@ this.setCurrentUser(user);

catch (e) {
const message = ((_a = e === null || e === void 0 ? void 0 : e.body) === null || _a === void 0 ? void 0 : _a.error) || "Error logging in.";
if (((_a = e === null || e === void 0 ? void 0 : e.body) === null || _a === void 0 ? void 0 : _a.type) === "record-not-found" &&
((_c = (_b = e === null || e === void 0 ? void 0 : e.body) === null || _b === void 0 ? void 0 : _b.hint) === null || _c === void 0 ? void 0 : _c["record-type"]) === "app-oauth-code" &&
(yield this._hasCurrentUser())) {
// We probably just weren't able to clean up the URL, so
// let's just ignore this error
return null;
}
const message = ((_d = e === null || e === void 0 ? void 0 : e.body) === null || _d === void 0 ? void 0 : _d.message) || "Error logging in.";
return { error: { message } };

@@ -804,2 +841,8 @@ }

}
_hasCurrentUser() {
return __awaiter(this, void 0, void 0, function* () {
const user = yield this._persister.getItem(currentUserKey);
return JSON.parse(user) != null;
});
}
changeCurrentUser(newUser) {

@@ -806,0 +849,0 @@ var _a;

@@ -8,9 +8,10 @@ declare type NonEmpty<T> = {

declare type WhereClauseValue = string | number | boolean | NonEmpty<WhereArgs>;
declare type WhereClauseWithOr = {
or?: BaseWhereClause[] | WhereClauseValue;
};
declare type BaseWhereClause = {
[key: string]: WhereClauseValue;
};
declare type WhereClause = WhereClauseWithOr | (WhereClauseWithOr & BaseWhereClause);
declare type WhereClauseWithCombinaton = {
or?: WhereClause[] | WhereClauseValue;
and?: WhereClause[] | WhereClauseValue;
};
declare type WhereClause = WhereClauseWithCombinaton | (WhereClauseWithCombinaton & BaseWhereClause);
declare type $Option = {

@@ -17,0 +18,0 @@ $?: {

@@ -48,2 +48,12 @@ "use strict";

});
const t3 = dummyQuery({
users: { $: { where: { and: [{ foo: 1 }] } } },
});
// You can have a field named and
const t4 = dummyQuery({
users: { $: { where: { and: "fieldNamedAnd" } } },
});
const t5 = dummyQuery({
users: { $: { where: { and: [{ or: [{ foo: 1 }] }] } } },
});
// ------------------

@@ -50,0 +60,0 @@ // Bad $ clauses fail

@@ -141,2 +141,3 @@ /**

}>;
_hasCurrentUser(): Promise<boolean>;
changeCurrentUser(newUser: any): Promise<void>;

@@ -143,0 +144,0 @@ updateUser(newUser: any): void;

@@ -705,3 +705,3 @@ "use strict";

}
// -----
// ----
// Auth

@@ -714,2 +714,3 @@ _replaceUrlAfterOAuth() {

if (url.searchParams.get(OAUTH_REDIRECT_PARAM)) {
const startUrl = url.toString();
url.searchParams.delete(OAUTH_REDIRECT_PARAM);

@@ -725,2 +726,31 @@ url.searchParams.delete("code");

history.replaceState(history.state, "", newPath);
// navigation is part of the HTML spec, but not supported by Safari
// or Firefox yet:
// https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API#browser_compatibility
if (
// @ts-ignore (waiting for ts support)
typeof navigation === "object" &&
// @ts-ignore (waiting for ts support)
typeof navigation.addEventListener === "function" &&
// @ts-ignore (waiting for ts support)
typeof navigation.removeEventListener === "function") {
let ran = false;
// The next.js app router will reset the URL when the router loads.
// This puts it back after the router loads.
const listener = (e) => {
var _a;
if (!ran) {
ran = true;
// @ts-ignore (waiting for ts support)
navigation.removeEventListener("navigate", listener);
if (!e.userInitiated &&
e.navigationType === "replace" &&
((_a = e.destination) === null || _a === void 0 ? void 0 : _a.url) === startUrl) {
history.replaceState(history.state, "", newPath);
}
}
};
// @ts-ignore (waiting for ts support)
navigation.addEventListener("navigate", listener);
}
}

@@ -733,3 +763,3 @@ }

_oauthLoginInit() {
var _a;
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {

@@ -759,3 +789,3 @@ if (typeof window === "undefined" ||

appId: this.config.appId,
code: code,
code,
});

@@ -766,3 +796,10 @@ this.setCurrentUser(user);

catch (e) {
const message = ((_a = e === null || e === void 0 ? void 0 : e.body) === null || _a === void 0 ? void 0 : _a.error) || "Error logging in.";
if (((_a = e === null || e === void 0 ? void 0 : e.body) === null || _a === void 0 ? void 0 : _a.type) === "record-not-found" &&
((_c = (_b = e === null || e === void 0 ? void 0 : e.body) === null || _b === void 0 ? void 0 : _b.hint) === null || _c === void 0 ? void 0 : _c["record-type"]) === "app-oauth-code" &&
(yield this._hasCurrentUser())) {
// We probably just weren't able to clean up the URL, so
// let's just ignore this error
return null;
}
const message = ((_d = e === null || e === void 0 ? void 0 : e.body) === null || _d === void 0 ? void 0 : _d.message) || "Error logging in.";
return { error: { message } };

@@ -832,2 +869,8 @@ }

}
_hasCurrentUser() {
return __awaiter(this, void 0, void 0, function* () {
const user = yield this._persister.getItem(currentUserKey);
return JSON.parse(user) != null;
});
}
changeCurrentUser(newUser) {

@@ -834,0 +877,0 @@ var _a;

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

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

@@ -68,2 +68,7 @@ // 1. patternMatch

}
if (pattern.and) {
return pattern.and.patterns.reduce((contexts, patterns) => {
return queryWhere(store, patterns, contexts);
}, contexts);
}
return contexts.flatMap((context) => querySingle(store, pattern, context));

@@ -70,0 +75,0 @@ }

@@ -181,2 +181,6 @@ import { query as datalogQuery } from "./datalog";

function isAndClauses([k, v]) {
return k === "and" && Array.isArray(v);
}
// Creates a makeVar that will namespace symbols for or clauses

@@ -193,9 +197,16 @@ // to prevent conflicts, except for the base etype

function parseWhereOrClauses(makeVar, store, etype, level, whereValue) {
function parseWhereClauses(
makeVar,
clauseType, /* 'or' | 'and' */
store,
etype,
level,
whereValue,
) {
const patterns = whereValue.map((w, i) => {
const makeOrVar = genMakeVar(makeVar, etype, i);
return parseWhere(makeOrVar, store, etype, level, w);
const makeNamespacedVar = genMakeVar(makeVar, etype, i);
return parseWhere(makeNamespacedVar, store, etype, level, w);
});
const joinSym = makeVar(etype, level);
return { or: { patterns, joinSym } };
return { [clauseType]: { patterns, joinSym } };
}

@@ -206,4 +217,7 @@

if (isOrClauses([k, v])) {
return parseWhereOrClauses(makeVar, store, etype, level, v);
return parseWhereClauses(makeVar, "or", store, etype, level, v);
}
if (isAndClauses([k, v])) {
return parseWhereClauses(makeVar, "and", store, etype, level, v);
}
const path = k.split(".");

@@ -210,0 +224,0 @@ return whereCondAttrPats(makeVar, store, etype, level, path, v);

@@ -15,3 +15,2 @@ // Query

type WhereClauseWithOr = { or?: BaseWhereClause[] | WhereClauseValue };
type BaseWhereClause = {

@@ -21,4 +20,11 @@ [key: string]: WhereClauseValue;

type WhereClause = WhereClauseWithOr | (WhereClauseWithOr & BaseWhereClause);
type WhereClauseWithCombinaton = {
or?: WhereClause[] | WhereClauseValue;
and?: WhereClause[] | WhereClauseValue;
};
type WhereClause =
| WhereClauseWithCombinaton
| (WhereClauseWithCombinaton & BaseWhereClause);
type $Option = { $?: { where: WhereClause } };

@@ -156,2 +162,12 @@

});
const t3 = dummyQuery({
users: { $: { where: { and: [{ foo: 1 }] } } },
});
// You can have a field named and
const t4 = dummyQuery({
users: { $: { where: { and: "fieldNamedAnd" } } },
});
const t5 = dummyQuery({
users: { $: { where: { and: [{ or: [{ foo: 1 }] }] } } },
});

@@ -158,0 +174,0 @@ // ------------------

@@ -792,5 +792,4 @@ // @ts-check

// -----
// ----
// Auth
_replaceUrlAfterOAuth() {

@@ -802,2 +801,3 @@ if (typeof URL === "undefined") {

if (url.searchParams.get(OAUTH_REDIRECT_PARAM)) {
const startUrl = url.toString();
url.searchParams.delete(OAUTH_REDIRECT_PARAM);

@@ -814,2 +814,35 @@ url.searchParams.delete("code");

history.replaceState(history.state, "", newPath);
// navigation is part of the HTML spec, but not supported by Safari
// or Firefox yet:
// https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API#browser_compatibility
if (
// @ts-ignore (waiting for ts support)
typeof navigation === "object" &&
// @ts-ignore (waiting for ts support)
typeof navigation.addEventListener === "function" &&
// @ts-ignore (waiting for ts support)
typeof navigation.removeEventListener === "function"
) {
let ran = false;
// The next.js app router will reset the URL when the router loads.
// This puts it back after the router loads.
const listener = (e) => {
if (!ran) {
ran = true;
// @ts-ignore (waiting for ts support)
navigation.removeEventListener("navigate", listener);
if (
!e.userInitiated &&
e.navigationType === "replace" &&
e.destination?.url === startUrl
) {
history.replaceState(history.state, "", newPath);
}
}
};
// @ts-ignore (waiting for ts support)
navigation.addEventListener("navigate", listener);
}
}

@@ -849,3 +882,3 @@ }

appId: this.config.appId,
code: code,
code,
});

@@ -855,3 +888,12 @@ this.setCurrentUser(user);

} catch (e) {
const message = e?.body?.error || "Error logging in.";
if (
e?.body?.type === "record-not-found" &&
e?.body?.hint?.["record-type"] === "app-oauth-code" &&
(await this._hasCurrentUser())
) {
// We probably just weren't able to clean up the URL, so
// let's just ignore this error
return null;
}
const message = e?.body?.message || "Error logging in.";
return { error: { message } };

@@ -925,2 +967,7 @@ }

async _hasCurrentUser() {
const user = await this._persister.getItem(currentUserKey);
return JSON.parse(user) != null;
}
async changeCurrentUser(newUser) {

@@ -927,0 +974,0 @@ await this.setCurrentUser(newUser);

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

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