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

@instantdb/core

Package Overview
Dependencies
Maintainers
0
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.14.9 to 0.14.10

19

dist/index.d.ts

@@ -169,2 +169,19 @@ import Reactor from "./Reactor";

shutdown(): void;
/**
* Use this for one-off queries.
* Returns local data if available, otherwise fetches from the server.
* Because we want to avoid stale data, this method will throw an error
* if the user is offline or there is no active connection to the server.
*
* @see https://instantdb.com/docs/instaql
*
* @example
*
* const resp = await db.queryOnce({ goals: {} });
* console.log(resp.data.goals)
*/
queryOnce<Q extends Schema extends InstantGraph<any, any> ? InstaQLQueryParams<Schema> : Exactly<Query, Q>>(query: Q): Promise<{
data: QueryResponse<Q, Schema, WithCardinalityInference>;
pageInfo: PageInfoResponse<Q>;
}>;
}

@@ -334,3 +351,3 @@ /**

declare function coerceQuery(o: any): any;
export { init, init_experimental, _init_internal, id, tx, txInit, lookup, i, getOps, coerceQuery, weakHash, IndexedDBStorage, WindowNetworkListener, InstantCore as InstantClient, Auth, Storage, type IDatabase, type RoomSchemaShape, type Query, type QueryResponse, type InstantObject, type Exactly, type TransactionChunk, type AuthState, type User, type AuthToken, type TxChunk, type SubscriptionState, type LifecycleSubscriptionState, type PresenceOpts, type PresenceSlice, type PresenceResponse, type InstaQLQueryParams, type InstantQuery, type InstantQueryResult, type InstantSchema, type InstantEntity, type InstantSchemaDatabase, type AttrsDefs, type CardinalityKind, type DataAttrDef, type EntitiesDef, type EntitiesWithLinks, type EntityDef, type InstantGraph, type LinkAttrDef, type LinkDef, type LinksDef, type ResolveAttrs, type ValueTypes, };
export { init, init_experimental, _init_internal, id, tx, txInit, lookup, i, getOps, coerceQuery, weakHash, IndexedDBStorage, WindowNetworkListener, InstantCore as InstantClient, Auth, Storage, type IDatabase, type RoomSchemaShape, type Query, type QueryResponse, type PageInfoResponse, type InstantObject, type Exactly, type TransactionChunk, type AuthState, type User, type AuthToken, type TxChunk, type SubscriptionState, type LifecycleSubscriptionState, type PresenceOpts, type PresenceSlice, type PresenceResponse, type InstaQLQueryParams, type InstantQuery, type InstantQueryResult, type InstantSchema, type InstantEntity, type InstantSchemaDatabase, type AttrsDefs, type CardinalityKind, type DataAttrDef, type EntitiesDef, type EntitiesWithLinks, type EntityDef, type InstantGraph, type LinkAttrDef, type LinkDef, type LinksDef, type ResolveAttrs, type ValueTypes, };
//# sourceMappingURL=index.d.ts.map

@@ -203,2 +203,18 @@ "use strict";

}
/**
* Use this for one-off queries.
* Returns local data if available, otherwise fetches from the server.
* Because we want to avoid stale data, this method will throw an error
* if the user is offline or there is no active connection to the server.
*
* @see https://instantdb.com/docs/instaql
*
* @example
*
* const resp = await db.queryOnce({ goals: {} });
* console.log(resp.data.goals)
*/
queryOnce(query) {
return this._reactor.queryOnce(query);
}
}

@@ -205,0 +221,0 @@ exports.InstantClient = InstantCore;

@@ -169,2 +169,19 @@ import Reactor from "./Reactor";

shutdown(): void;
/**
* Use this for one-off queries.
* Returns local data if available, otherwise fetches from the server.
* Because we want to avoid stale data, this method will throw an error
* if the user is offline or there is no active connection to the server.
*
* @see https://instantdb.com/docs/instaql
*
* @example
*
* const resp = await db.queryOnce({ goals: {} });
* console.log(resp.data.goals)
*/
queryOnce<Q extends Schema extends InstantGraph<any, any> ? InstaQLQueryParams<Schema> : Exactly<Query, Q>>(query: Q): Promise<{
data: QueryResponse<Q, Schema, WithCardinalityInference>;
pageInfo: PageInfoResponse<Q>;
}>;
}

@@ -334,3 +351,3 @@ /**

declare function coerceQuery(o: any): any;
export { init, init_experimental, _init_internal, id, tx, txInit, lookup, i, getOps, coerceQuery, weakHash, IndexedDBStorage, WindowNetworkListener, InstantCore as InstantClient, Auth, Storage, type IDatabase, type RoomSchemaShape, type Query, type QueryResponse, type InstantObject, type Exactly, type TransactionChunk, type AuthState, type User, type AuthToken, type TxChunk, type SubscriptionState, type LifecycleSubscriptionState, type PresenceOpts, type PresenceSlice, type PresenceResponse, type InstaQLQueryParams, type InstantQuery, type InstantQueryResult, type InstantSchema, type InstantEntity, type InstantSchemaDatabase, type AttrsDefs, type CardinalityKind, type DataAttrDef, type EntitiesDef, type EntitiesWithLinks, type EntityDef, type InstantGraph, type LinkAttrDef, type LinkDef, type LinksDef, type ResolveAttrs, type ValueTypes, };
export { init, init_experimental, _init_internal, id, tx, txInit, lookup, i, getOps, coerceQuery, weakHash, IndexedDBStorage, WindowNetworkListener, InstantCore as InstantClient, Auth, Storage, type IDatabase, type RoomSchemaShape, type Query, type QueryResponse, type PageInfoResponse, type InstantObject, type Exactly, type TransactionChunk, type AuthState, type User, type AuthToken, type TxChunk, type SubscriptionState, type LifecycleSubscriptionState, type PresenceOpts, type PresenceSlice, type PresenceResponse, type InstaQLQueryParams, type InstantQuery, type InstantQueryResult, type InstantSchema, type InstantEntity, type InstantSchemaDatabase, type AttrsDefs, type CardinalityKind, type DataAttrDef, type EntitiesDef, type EntitiesWithLinks, type EntityDef, type InstantGraph, type LinkAttrDef, type LinkDef, type LinksDef, type ResolveAttrs, type ValueTypes, };
//# sourceMappingURL=index.d.ts.map

@@ -184,2 +184,18 @@ import Reactor from "./Reactor";

}
/**
* Use this for one-off queries.
* Returns local data if available, otherwise fetches from the server.
* Because we want to avoid stale data, this method will throw an error
* if the user is offline or there is no active connection to the server.
*
* @see https://instantdb.com/docs/instaql
*
* @example
*
* const resp = await db.queryOnce({ goals: {} });
* console.log(resp.data.goals)
*/
queryOnce(query) {
return this._reactor.queryOnce(query);
}
}

@@ -186,0 +202,0 @@ /**

@@ -14,3 +14,13 @@ /**

pendingMutations: PersistedObject;
queryCbs: {};
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
queryCbs: Record<string, Array<{
q: any;
cb: (data: any) => any;
}>>;
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
queryOnceDfds: Record<string, Array<{
q: any;
eventId: string;
dfd: Deferred;
}>>;
authCbs: any[];

@@ -98,4 +108,6 @@ attrsCbs: any[];

_handleReceiveError(msg: any): void;
notifyQueryOnceError(hash: any, eventId: any, e: any): void;
_setAttrs(attrs: any): void;
getPreviousResult: (q: any) => any;
_startQuerySub(q: any, hash: any): string;
/**

@@ -112,2 +124,6 @@ * When a user subscribes to a query the following side effects occur:

subscribeQuery(q: any, cb: any): () => void;
queryOnce(q: any): Promise<any>;
_completeQueryOnce(q: any, hash: any, dfd: any): void;
_unsubQuery(q: any, hash: any, cb: any): void;
_cleanupQuery(q: any, hash: any): void;
_rewriteMutations(attrs: any, muts: any): any;

@@ -119,3 +135,4 @@ optimisticAttrs(): any;

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

@@ -281,4 +298,5 @@ notifyAll(): void;

import { PersistedObject } from "./utils/PersistedObject";
import { Deferred } from "./utils/Deferred";
import IndexedDBStorage from "./IndexedDBStorage";
import WindowNetworkListener from "./WindowNetworkListener";
//# sourceMappingURL=Reactor.d.ts.map

110

dist/module/Reactor.js

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

};
const QUERY_ONCE_TIMEOUT = 5000;
const WS_OPEN_STATUS = 1;

@@ -82,3 +83,6 @@ const defaultConfig = {

this.status = STATUS.CONNECTING;
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
this.queryCbs = {};
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
this.queryOnceDfds = {};
this.authCbs = [];

@@ -167,7 +171,5 @@ this.attrsCbs = [];

this.notifyOne = (hash) => {
var _a;
const cbs = this.queryCbs[hash] || [];
if (!cbs)
return;
const prevData = (_a = this._dataForQueryCache[hash]) === null || _a === void 0 ? void 0 : _a.data;
var _a, _b;
const cbs = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
const prevData = (_b = this._dataForQueryCache[hash]) === null || _b === void 0 ? void 0 : _b.data;
const data = this.dataForQuery(hash);

@@ -178,7 +180,16 @@ if (!data)

return;
cbs.forEach((cb) => cb(data));
cbs.forEach((r) => r.cb(data));
};
this.notifyQueryError = (hash, msg) => {
this.notifyOneQueryOnce = (hash) => {
var _a;
const dfds = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
const data = this.dataForQuery(hash);
dfds.forEach((r) => {
this._completeQueryOnce(r.q, hash, r.dfd);
r.dfd.resolve(data);
});
};
this.notifyQueryError = (hash, error) => {
const cbs = this.queryCbs[hash] || [];
cbs.forEach((cb) => cb({ error: msg }));
cbs.forEach((r) => r.cb({ error }));
};

@@ -405,2 +416,5 @@ /** Applies transactions locally and sends transact message to server */

break;
case "add-query-exists":
this.notifyOneQueryOnce(weakHash(msg.q));
break;
case "add-query-ok":

@@ -419,2 +433,3 @@ const { q, result, "processed-tx-id": addQueryTxId } = msg;

this.notifyOne(hash);
this.notifyOneQueryOnce(hash);
break;

@@ -526,2 +541,5 @@ case "refresh-ok":

const prevMutation = this.pendingMutations.currentValue.get(eventId);
const errorMessage = {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
};
if (prevMutation) {

@@ -538,11 +556,10 @@ // This must be a transaction error

if (q) {
const hash = weakHash(q);
// This must be a query error
this.querySubs.set((prev) => {
const hash = weakHash(q);
delete prev[hash];
return prev;
});
this.notifyQueryError(weakHash(q), {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
});
this.notifyQueryError(weakHash(q), errorMessage);
this.notifyQueryOnceError(hash, eventId, errorMessage);
return;

@@ -559,5 +576,2 @@ }

// We failed to init
const errorMessage = {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
};
this._setStatus(STATUS.ERRORED, errorMessage);

@@ -577,2 +591,9 @@ this.notifyAll();

}
notifyQueryOnceError(hash, eventId, e) {
var _a;
const r = (_a = this.queryOnceDfds[hash]) === null || _a === void 0 ? void 0 : _a.find((r) => r.eventId === eventId);
if (!r)
return;
r.dfd.reject(e);
}
_setAttrs(attrs) {

@@ -585,2 +606,11 @@ this.attrs = attrs.reduce((acc, attr) => {

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

@@ -597,11 +627,4 @@ * When a user subscribes to a query the following side effects occur:

subscribeQuery(q, cb) {
const eventId = uuid();
var _a;
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._trySendAuthed(eventId, { op: "add-query", q });
const prevResult = this.getPreviousResult(q);

@@ -611,6 +634,45 @@ if (prevResult) {

}
this.queryCbs[hash] = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
this.queryCbs[hash].push({ q, cb });
this._startQuerySub(q, hash);
return () => {
this.queryCbs[hash] = this.queryCbs[hash].filter((x) => x !== cb);
this._unsubQuery(q, hash, cb);
};
}
queryOnce(q) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (!this._isOnline) {
throw new Error("Offline: Cannot execute query because the device is offline.");
}
const hash = weakHash(q);
const dfd = new Deferred();
const eventId = this._startQuerySub(q, hash);
this.queryOnceDfds[hash] = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
this.queryOnceDfds[hash].push({ q, dfd, eventId });
setTimeout(() => dfd.reject(new Error("Query timed out")), QUERY_ONCE_TIMEOUT);
return dfd.promise;
});
}
_completeQueryOnce(q, hash, dfd) {
if (!this.queryOnceDfds[hash])
return;
this.queryOnceDfds[hash] = this.queryOnceDfds[hash].filter((r) => r.dfd !== dfd);
this._cleanupQuery(q, hash);
}
_unsubQuery(q, hash, cb) {
if (!this.queryCbs[hash])
return;
this.queryCbs[hash] = this.queryCbs[hash].filter((r) => r.cb !== cb);
this._cleanupQuery(q, hash);
}
_cleanupQuery(q, hash) {
var _a, _b;
const hasListeners = ((_a = this.queryCbs[hash]) === null || _a === void 0 ? void 0 : _a.length) || ((_b = this.queryOnceDfds[hash]) === null || _b === void 0 ? void 0 : _b.length);
if (hasListeners)
return;
delete this.queryCbs[hash];
delete this.queryOnceDfds[hash];
this._trySendAuthed(uuid(), { op: "remove-query", q });
}
// When we `pushTx`, it's possible that we don't yet have `this.attrs`

@@ -617,0 +679,0 @@ // This means that `tx-steps` in `pendingMutations` will include `add-attr`

@@ -14,3 +14,13 @@ /**

pendingMutations: PersistedObject;
queryCbs: {};
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
queryCbs: Record<string, Array<{
q: any;
cb: (data: any) => any;
}>>;
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
queryOnceDfds: Record<string, Array<{
q: any;
eventId: string;
dfd: Deferred;
}>>;
authCbs: any[];

@@ -98,4 +108,6 @@ attrsCbs: any[];

_handleReceiveError(msg: any): void;
notifyQueryOnceError(hash: any, eventId: any, e: any): void;
_setAttrs(attrs: any): void;
getPreviousResult: (q: any) => any;
_startQuerySub(q: any, hash: any): string;
/**

@@ -112,2 +124,6 @@ * When a user subscribes to a query the following side effects occur:

subscribeQuery(q: any, cb: any): () => void;
queryOnce(q: any): Promise<any>;
_completeQueryOnce(q: any, hash: any, dfd: any): void;
_unsubQuery(q: any, hash: any, cb: any): void;
_cleanupQuery(q: any, hash: any): void;
_rewriteMutations(attrs: any, muts: any): any;

@@ -119,3 +135,4 @@ optimisticAttrs(): any;

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

@@ -281,4 +298,5 @@ notifyAll(): void;

import { PersistedObject } from "./utils/PersistedObject";
import { Deferred } from "./utils/Deferred";
import IndexedDBStorage from "./IndexedDBStorage";
import WindowNetworkListener from "./WindowNetworkListener";
//# sourceMappingURL=Reactor.d.ts.map

@@ -62,2 +62,3 @@ "use strict";

};
const QUERY_ONCE_TIMEOUT = 5000;
const WS_OPEN_STATUS = 1;

@@ -110,3 +111,6 @@ const defaultConfig = {

this.status = STATUS.CONNECTING;
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
this.queryCbs = {};
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
this.queryOnceDfds = {};
this.authCbs = [];

@@ -195,7 +199,5 @@ this.attrsCbs = [];

this.notifyOne = (hash) => {
var _a;
const cbs = this.queryCbs[hash] || [];
if (!cbs)
return;
const prevData = (_a = this._dataForQueryCache[hash]) === null || _a === void 0 ? void 0 : _a.data;
var _a, _b;
const cbs = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
const prevData = (_b = this._dataForQueryCache[hash]) === null || _b === void 0 ? void 0 : _b.data;
const data = this.dataForQuery(hash);

@@ -206,7 +208,16 @@ if (!data)

return;
cbs.forEach((cb) => cb(data));
cbs.forEach((r) => r.cb(data));
};
this.notifyQueryError = (hash, msg) => {
this.notifyOneQueryOnce = (hash) => {
var _a;
const dfds = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
const data = this.dataForQuery(hash);
dfds.forEach((r) => {
this._completeQueryOnce(r.q, hash, r.dfd);
r.dfd.resolve(data);
});
};
this.notifyQueryError = (hash, error) => {
const cbs = this.queryCbs[hash] || [];
cbs.forEach((cb) => cb({ error: msg }));
cbs.forEach((r) => r.cb({ error }));
};

@@ -433,2 +444,5 @@ /** Applies transactions locally and sends transact message to server */

break;
case "add-query-exists":
this.notifyOneQueryOnce((0, weakHash_1.default)(msg.q));
break;
case "add-query-ok":

@@ -447,2 +461,3 @@ const { q, result, "processed-tx-id": addQueryTxId } = msg;

this.notifyOne(hash);
this.notifyOneQueryOnce(hash);
break;

@@ -554,2 +569,5 @@ case "refresh-ok":

const prevMutation = this.pendingMutations.currentValue.get(eventId);
const errorMessage = {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
};
if (prevMutation) {

@@ -566,11 +584,10 @@ // This must be a transaction error

if (q) {
const hash = (0, weakHash_1.default)(q);
// This must be a query error
this.querySubs.set((prev) => {
const hash = (0, weakHash_1.default)(q);
delete prev[hash];
return prev;
});
this.notifyQueryError((0, weakHash_1.default)(q), {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
});
this.notifyQueryError((0, weakHash_1.default)(q), errorMessage);
this.notifyQueryOnceError(hash, eventId, errorMessage);
return;

@@ -587,5 +604,2 @@ }

// We failed to init
const errorMessage = {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
};
this._setStatus(STATUS.ERRORED, errorMessage);

@@ -605,2 +619,9 @@ this.notifyAll();

}
notifyQueryOnceError(hash, eventId, e) {
var _a;
const r = (_a = this.queryOnceDfds[hash]) === null || _a === void 0 ? void 0 : _a.find((r) => r.eventId === eventId);
if (!r)
return;
r.dfd.reject(e);
}
_setAttrs(attrs) {

@@ -613,2 +634,11 @@ this.attrs = attrs.reduce((acc, attr) => {

}
_startQuerySub(q, hash) {
const eventId = (0, uuid_1.default)();
this.querySubs.set((prev) => {
prev[hash] = prev[hash] || { q, result: null, eventId };
return prev;
});
this._trySendAuthed(eventId, { op: "add-query", q });
return eventId;
}
/**

@@ -625,11 +655,4 @@ * When a user subscribes to a query the following side effects occur:

subscribeQuery(q, cb) {
const eventId = (0, uuid_1.default)();
var _a;
const hash = (0, weakHash_1.default)(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._trySendAuthed(eventId, { op: "add-query", q });
const prevResult = this.getPreviousResult(q);

@@ -639,6 +662,45 @@ if (prevResult) {

}
this.queryCbs[hash] = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
this.queryCbs[hash].push({ q, cb });
this._startQuerySub(q, hash);
return () => {
this.queryCbs[hash] = this.queryCbs[hash].filter((x) => x !== cb);
this._unsubQuery(q, hash, cb);
};
}
queryOnce(q) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (!this._isOnline) {
throw new Error("Offline: Cannot execute query because the device is offline.");
}
const hash = (0, weakHash_1.default)(q);
const dfd = new Deferred_1.Deferred();
const eventId = this._startQuerySub(q, hash);
this.queryOnceDfds[hash] = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
this.queryOnceDfds[hash].push({ q, dfd, eventId });
setTimeout(() => dfd.reject(new Error("Query timed out")), QUERY_ONCE_TIMEOUT);
return dfd.promise;
});
}
_completeQueryOnce(q, hash, dfd) {
if (!this.queryOnceDfds[hash])
return;
this.queryOnceDfds[hash] = this.queryOnceDfds[hash].filter((r) => r.dfd !== dfd);
this._cleanupQuery(q, hash);
}
_unsubQuery(q, hash, cb) {
if (!this.queryCbs[hash])
return;
this.queryCbs[hash] = this.queryCbs[hash].filter((r) => r.cb !== cb);
this._cleanupQuery(q, hash);
}
_cleanupQuery(q, hash) {
var _a, _b;
const hasListeners = ((_a = this.queryCbs[hash]) === null || _a === void 0 ? void 0 : _a.length) || ((_b = this.queryOnceDfds[hash]) === null || _b === void 0 ? void 0 : _b.length);
if (hasListeners)
return;
delete this.queryCbs[hash];
delete this.queryOnceDfds[hash];
this._trySendAuthed((0, uuid_1.default)(), { op: "remove-query", q });
}
// When we `pushTx`, it's possible that we don't yet have `this.attrs`

@@ -645,0 +707,0 @@ // This means that `tx-steps` in `pendingMutations` will include `add-attr`

{
"name": "@instantdb/core",
"version": "v0.14.9",
"version": "v0.14.10",
"description": "Instant's core local abstraction",

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

@@ -390,2 +390,28 @@ import Reactor from "./Reactor";

}
/**
* Use this for one-off queries.
* Returns local data if available, otherwise fetches from the server.
* Because we want to avoid stale data, this method will throw an error
* if the user is offline or there is no active connection to the server.
*
* @see https://instantdb.com/docs/instaql
*
* @example
*
* const resp = await db.queryOnce({ goals: {} });
* console.log(resp.data.goals)
*/
queryOnce<
Q extends Schema extends InstantGraph<any, any>
? InstaQLQueryParams<Schema>
: Exactly<Query, Q>,
>(
query: Q,
): Promise<{
data: QueryResponse<Q, Schema, WithCardinalityInference>;
pageInfo: PageInfoResponse<Q>;
}> {
return this._reactor.queryOnce(query);
}
}

@@ -617,2 +643,3 @@

type QueryResponse,
type PageInfoResponse,
type InstantObject,

@@ -619,0 +646,0 @@ type Exactly,

@@ -27,2 +27,4 @@ // @ts-check

const QUERY_ONCE_TIMEOUT = 5000;
const WS_OPEN_STATUS = 1;

@@ -90,3 +92,6 @@

/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
queryCbs = {};
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
queryOnceDfds = {};
authCbs = [];

@@ -361,2 +366,5 @@ attrsCbs = [];

break;
case "add-query-exists":
this.notifyOneQueryOnce(weakHash(msg.q));
break;
case "add-query-ok":

@@ -380,2 +388,3 @@ const { q, result, "processed-tx-id": addQueryTxId } = msg;

this.notifyOne(hash);
this.notifyOneQueryOnce(hash);
break;

@@ -503,2 +512,6 @@ case "refresh-ok":

const prevMutation = this.pendingMutations.currentValue.get(eventId);
const errorMessage = {
message: msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
};
if (prevMutation) {

@@ -516,12 +529,11 @@ // This must be a transaction error

if (q) {
const hash = weakHash(q);
// This must be a query error
this.querySubs.set((prev) => {
const hash = weakHash(q);
delete prev[hash];
return prev;
});
this.notifyQueryError(weakHash(q), {
message:
msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
});
this.notifyQueryError(weakHash(q), errorMessage);
this.notifyQueryOnceError(hash, eventId, errorMessage);
return;

@@ -542,6 +554,3 @@ }

// We failed to init
const errorMessage = {
message:
msg.message || "Uh-oh, something went wrong. Ping Joe & Stopa.",
};
this._setStatus(STATUS.ERRORED, errorMessage);

@@ -565,2 +574,8 @@ this.notifyAll();

notifyQueryOnceError(hash, eventId, e) {
const r = this.queryOnceDfds[hash]?.find((r) => r.eventId === eventId);
if (!r) return;
r.dfd.reject(e);
}
_setAttrs(attrs) {

@@ -583,2 +598,13 @@ this.attrs = attrs.reduce((acc, attr) => {

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

@@ -595,12 +621,4 @@ * When a user subscribes to a query the following side effects occur:

subscribeQuery(q, cb) {
const eventId = uuid();
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._trySendAuthed(eventId, { op: "add-query", q });
const prevResult = this.getPreviousResult(q);

@@ -610,7 +628,66 @@ if (prevResult) {

}
this.queryCbs[hash] = this.queryCbs[hash] ?? [];
this.queryCbs[hash].push({ q, cb });
this._startQuerySub(q, hash);
return () => {
this.queryCbs[hash] = this.queryCbs[hash].filter((x) => x !== cb);
this._unsubQuery(q, hash, cb);
};
}
async queryOnce(q) {
if (!this._isOnline) {
throw new Error(
"Offline: Cannot execute query because the device is offline.",
);
}
const hash = weakHash(q);
const dfd = new Deferred();
const eventId = this._startQuerySub(q, hash);
this.queryOnceDfds[hash] = this.queryOnceDfds[hash] ?? [];
this.queryOnceDfds[hash].push({ q, dfd, eventId });
setTimeout(
() => dfd.reject(new Error("Query timed out")),
QUERY_ONCE_TIMEOUT,
);
return dfd.promise;
}
_completeQueryOnce(q, hash, dfd) {
if (!this.queryOnceDfds[hash]) return;
this.queryOnceDfds[hash] = this.queryOnceDfds[hash].filter(
(r) => r.dfd !== dfd,
);
this._cleanupQuery(q, hash);
}
_unsubQuery(q, hash, cb) {
if (!this.queryCbs[hash]) return;
this.queryCbs[hash] = this.queryCbs[hash].filter((r) => r.cb !== cb);
this._cleanupQuery(q, hash);
}
_cleanupQuery(q, hash) {
const hasListeners =
this.queryCbs[hash]?.length || this.queryOnceDfds[hash]?.length;
if (hasListeners) return;
delete this.queryCbs[hash];
delete this.queryOnceDfds[hash];
this._trySendAuthed(uuid(), { op: "remove-query", q });
}
// When we `pushTx`, it's possible that we don't yet have `this.attrs`

@@ -764,14 +841,25 @@ // This means that `tx-steps` in `pendingMutations` will include `add-attr`

notifyOne = (hash) => {
const cbs = this.queryCbs[hash] || [];
if (!cbs) return;
const cbs = this.queryCbs[hash] ?? [];
const prevData = this._dataForQueryCache[hash]?.data;
const data = this.dataForQuery(hash);
if (!data) return;
if (areObjectsDeepEqual(data, prevData)) return;
cbs.forEach((cb) => cb(data));
cbs.forEach((r) => r.cb(data));
};
notifyQueryError = (hash, msg) => {
notifyOneQueryOnce = (hash) => {
const dfds = this.queryOnceDfds[hash] ?? [];
const data = this.dataForQuery(hash);
dfds.forEach((r) => {
this._completeQueryOnce(r.q, hash, r.dfd);
r.dfd.resolve(data);
});
};
notifyQueryError = (hash, error) => {
const cbs = this.queryCbs[hash] || [];
cbs.forEach((cb) => cb({ error: msg }));
cbs.forEach((r) => r.cb({ error }));
};

@@ -778,0 +866,0 @@

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 too big to display

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