Socket
Socket
Sign inDemoInstall

@n1ru4l/in-memory-live-query-store

Package Overview
Dependencies
5
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.0-alpha-51b566b.0 to 0.9.0-alpha-e02cfcd.0

148

esm/index.js
import { visit, visitWithTypeInfo, isNonNullType, isScalarType, execute, getOperationAST, GraphQLError, defaultFieldResolver, TypeInfo } from 'graphql';
import { mapSchema, MapperKind } from '@graphql-tools/utils';
import { makePushPullAsyncIterableIterator, isAsyncIterable } from '@n1ru4l/push-pull-async-iterable-iterator';
import { mapSchema, MapperKind, isAsyncIterable } from '@graphql-tools/utils';
import { Repeater } from '@repeaterjs/repeater';
import { getLiveDirectiveNode, getLiveDirectiveArgumentValues } from '@n1ru4l/graphql-live-query';

@@ -176,3 +176,2 @@ import { getArgumentValues } from 'graphql/execution/values.js';

var _a, _b;
const ORIGINAL_CONTEXT_SYMBOL = Symbol("ORIGINAL_CONTEXT");

@@ -186,34 +185,16 @@ const addResourceIdentifierCollectorToSchema = (schema, idFieldName) => mapSchema(schema, {

newFieldConfig.resolve = (src, args, context, info) => {
var _a, _b;
var _a;
if (!context || ORIGINAL_CONTEXT_SYMBOL in context === false) {
return resolve(src, args, context, info);
}
const liveQueyContext = context;
const result = resolve(src, args, liveQueyContext[ORIGINAL_CONTEXT_SYMBOL], info);
const collectResourceIdentifier = context.collectResourceIdentifier;
const addResourceIdentifier = context.addResourceIdentifier;
context = context[ORIGINAL_CONTEXT_SYMBOL];
const result = resolve(src, args, context, info);
const fieldConfigExtensions = fieldConfig.extensions;
if ((_a = fieldConfigExtensions === null || fieldConfigExtensions === void 0 ? void 0 : fieldConfigExtensions.liveQuery) === null || _a === void 0 ? void 0 : _a.collectResourceIdentifiers) {
liveQueyContext.addResourceIdentifier(fieldConfigExtensions.liveQuery.collectResourceIdentifiers(src, args));
addResourceIdentifier(fieldConfigExtensions.liveQuery.collectResourceIdentifiers(src, args));
}
const fieldCoordinate = `${typename}.${fieldName}`;
const indicesForCoordinate = (_b = liveQueyContext.indices) === null || _b === void 0 ? void 0 : _b.get(fieldCoordinate);
if (indicesForCoordinate) {
for (const index of indicesForCoordinate) {
let parts = [];
for (const part of index) {
if (Array.isArray(part)) {
if (args[part[0]] === part[1]) {
parts.push(`${part[0]}:"${args[part[0]]}"`);
}
}
else if (args[part] !== undefined) {
parts.push(`${part}:"${args[part]}"`);
}
}
if (parts.length) {
liveQueyContext.addResourceIdentifier(`${fieldCoordinate}(${parts.join(",")})`);
}
}
}
if (isIDField) {
runWith(result, (id) => liveQueyContext.collectResourceIdentifier({ typename, id }));
runWith(result, (id) => collectResourceIdentifier({ typename, id }));
}

@@ -226,5 +207,2 @@ return result;

const defaultResourceIdentifierNormalizer = (params) => `${params.typename}:${params.id}`;
const nextTick = (_b = (_a = (typeof process === "object" && typeof process.nextTick === "function"
? process.nextTick
: undefined)) !== null && _a !== void 0 ? _a : setImmediate) !== null && _b !== void 0 ? _b : setTimeout;
class InMemoryLiveQueryStore {

@@ -239,3 +217,2 @@ constructor(params) {

this._idFieldName = "id";
this._indices = null;
this.makeExecute = (execute) => (args) => {

@@ -286,14 +263,22 @@ const { schema: inputSchema, document, rootValue, contextValue, variableValues, operationName, ...additionalArguments } = args;

}));
const { asyncIterableIterator: iterator, pushValue } = makePushPullAsyncIterableIterator();
// keep track that current execution is the latest in order to prevent race-conditions :)
let executionCounter = 0;
let previousIdentifier = new Set(rootFieldIdentifier);
const record = {
iterator,
pushValue,
run: () => {
const context = this;
return new Repeater(async function liveQueryRepeater(push, onStop) {
// utils for throttle
let cancelThrottle;
let run;
let executionCounter = 0;
let previousIdentifier = new Set(rootFieldIdentifier);
function scheduleRun() {
run();
}
function dispose() {
cancelThrottle === null || cancelThrottle === void 0 ? void 0 : cancelThrottle();
context._resourceTracker.release(scheduleRun, previousIdentifier);
}
onStop.then(dispose);
run = function run() {
executionCounter = executionCounter + 1;
const counter = executionCounter;
const newIdentifier = new Set(rootFieldIdentifier);
const collectResourceIdentifier = (parameter) => newIdentifier.add(this._buildResourceIdentifier(parameter));
const collectResourceIdentifier = (parameter) => newIdentifier.add(context._buildResourceIdentifier(parameter));
const addResourceIdentifier = (values) => {

@@ -311,8 +296,2 @@ if (isNone(values)) {

};
const context = {
[ORIGINAL_CONTEXT_SYMBOL]: contextValue,
collectResourceIdentifier,
addResourceIdentifier,
indices: this._indices,
};
const result = execute({

@@ -323,3 +302,7 @@ schema,

rootValue,
contextValue: context,
contextValue: {
[ORIGINAL_CONTEXT_SYMBOL]: contextValue,
collectResourceIdentifier,
addResourceIdentifier,
},
variableValues,

@@ -329,30 +312,13 @@ ...additionalArguments,

});
// result cannot be a AsyncIterableIterator if the `NoLiveMixedWithDeferStreamRule` was used.
// in case anyone forgot to add it we just panic and stop the execution :)
const handleAsyncIterator = (iterator) => {
var _a;
(_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator);
record.pushValue({
errors: [
new GraphQLError(`"execute" returned a AsyncIterator instead of a MaybePromise<ExecutionResult>. The "NoLiveMixedWithDeferStreamRule" rule might have been skipped.`),
],
});
// delay to next tick to ensure the error is delivered to listeners.
// TODO: figure out whether there is a better way for doing this.
nextTick(() => {
record.iterator.return();
});
this._resourceTracker.release(record, previousIdentifier);
};
runWith(result, (result) => {
if (isAsyncIterable(result)) {
handleAsyncIterator(result);
onStop(new Error(`"execute" returned a AsyncIterator instead of a MaybePromise<ExecutionResult>. The "NoLiveMixedWithDeferStreamRule" rule might have been skipped.`));
return;
}
if (counter === executionCounter) {
this._resourceTracker.track(record, previousIdentifier, newIdentifier);
context._resourceTracker.track(scheduleRun, previousIdentifier, newIdentifier);
previousIdentifier = newIdentifier;
const liveResult = result;
liveResult.isLive = true;
if (this._includeIdentifierExtension === true) {
if (context._includeIdentifierExtension === true) {
if (!liveResult.extensions) {

@@ -364,25 +330,14 @@ liveResult.extensions = {};

}
record.pushValue(liveResult);
push(liveResult);
}
});
},
};
// utils for throttle
let cancelThrottle;
if (isSome(throttleValue)) {
const { run, cancel } = throttle(record.run, throttleValue);
record.run = run;
cancelThrottle = cancel;
}
this._resourceTracker.register(record, previousIdentifier);
// Execute initial query
record.run();
// TODO: figure out how we can do this stuff without monkey-patching the iterator
const originalReturn = iterator.return.bind(iterator);
iterator.return = () => {
cancelThrottle === null || cancelThrottle === void 0 ? void 0 : cancelThrottle();
this._resourceTracker.release(record, previousIdentifier);
return originalReturn();
};
return iterator;
};
if (isSome(throttleValue)) {
const throttled = throttle(run, throttleValue);
run = throttled.run;
cancelThrottle = throttled.cancel;
}
context._resourceTracker.register(scheduleRun, previousIdentifier);
scheduleRun();
});
};

@@ -403,13 +358,2 @@ /** @deprecated Please use InMemoryLiveQueryStore.makeExecute instead. */

}
if (params === null || params === void 0 ? void 0 : params.indexBy) {
this._indices = new Map();
for (const { field, args } of params.indexBy) {
let indices = this._indices.get(field);
if (!indices) {
indices = [];
this._indices.set(field, indices);
}
indices.push(args);
}
}
this._includeIdentifierExtension =

@@ -441,4 +385,4 @@ (_a = params === null || params === void 0 ? void 0 : params.includeIdentifierExtension) !== null && _a !== void 0 ? _a : (typeof process === "undefined"

const records = this._resourceTracker.getRecordsForIdentifiers(identifiers);
for (const record of records) {
record.run();
for (const run of records) {
run();
}

@@ -445,0 +389,0 @@ }

@@ -7,3 +7,3 @@ 'use strict';

const utils = require('@graphql-tools/utils');
const pushPullAsyncIterableIterator = require('@n1ru4l/push-pull-async-iterable-iterator');
const repeater = require('@repeaterjs/repeater');
const graphqlLiveQuery = require('@n1ru4l/graphql-live-query');

@@ -181,3 +181,2 @@ const values_js = require('graphql/execution/values.js');

var _a, _b;
const ORIGINAL_CONTEXT_SYMBOL = Symbol("ORIGINAL_CONTEXT");

@@ -191,34 +190,16 @@ const addResourceIdentifierCollectorToSchema = (schema, idFieldName) => utils.mapSchema(schema, {

newFieldConfig.resolve = (src, args, context, info) => {
var _a, _b;
var _a;
if (!context || ORIGINAL_CONTEXT_SYMBOL in context === false) {
return resolve(src, args, context, info);
}
const liveQueyContext = context;
const result = resolve(src, args, liveQueyContext[ORIGINAL_CONTEXT_SYMBOL], info);
const collectResourceIdentifier = context.collectResourceIdentifier;
const addResourceIdentifier = context.addResourceIdentifier;
context = context[ORIGINAL_CONTEXT_SYMBOL];
const result = resolve(src, args, context, info);
const fieldConfigExtensions = fieldConfig.extensions;
if ((_a = fieldConfigExtensions === null || fieldConfigExtensions === void 0 ? void 0 : fieldConfigExtensions.liveQuery) === null || _a === void 0 ? void 0 : _a.collectResourceIdentifiers) {
liveQueyContext.addResourceIdentifier(fieldConfigExtensions.liveQuery.collectResourceIdentifiers(src, args));
addResourceIdentifier(fieldConfigExtensions.liveQuery.collectResourceIdentifiers(src, args));
}
const fieldCoordinate = `${typename}.${fieldName}`;
const indicesForCoordinate = (_b = liveQueyContext.indices) === null || _b === void 0 ? void 0 : _b.get(fieldCoordinate);
if (indicesForCoordinate) {
for (const index of indicesForCoordinate) {
let parts = [];
for (const part of index) {
if (Array.isArray(part)) {
if (args[part[0]] === part[1]) {
parts.push(`${part[0]}:"${args[part[0]]}"`);
}
}
else if (args[part] !== undefined) {
parts.push(`${part}:"${args[part]}"`);
}
}
if (parts.length) {
liveQueyContext.addResourceIdentifier(`${fieldCoordinate}(${parts.join(",")})`);
}
}
}
if (isIDField) {
runWith(result, (id) => liveQueyContext.collectResourceIdentifier({ typename, id }));
runWith(result, (id) => collectResourceIdentifier({ typename, id }));
}

@@ -231,5 +212,2 @@ return result;

const defaultResourceIdentifierNormalizer = (params) => `${params.typename}:${params.id}`;
const nextTick = (_b = (_a = (typeof process === "object" && typeof process.nextTick === "function"
? process.nextTick
: undefined)) !== null && _a !== void 0 ? _a : setImmediate) !== null && _b !== void 0 ? _b : setTimeout;
class InMemoryLiveQueryStore {

@@ -244,3 +222,2 @@ constructor(params) {

this._idFieldName = "id";
this._indices = null;
this.makeExecute = (execute) => (args) => {

@@ -291,14 +268,22 @@ const { schema: inputSchema, document, rootValue, contextValue, variableValues, operationName, ...additionalArguments } = args;

}));
const { asyncIterableIterator: iterator, pushValue } = pushPullAsyncIterableIterator.makePushPullAsyncIterableIterator();
// keep track that current execution is the latest in order to prevent race-conditions :)
let executionCounter = 0;
let previousIdentifier = new Set(rootFieldIdentifier);
const record = {
iterator,
pushValue,
run: () => {
const context = this;
return new repeater.Repeater(async function liveQueryRepeater(push, onStop) {
// utils for throttle
let cancelThrottle;
let run;
let executionCounter = 0;
let previousIdentifier = new Set(rootFieldIdentifier);
function scheduleRun() {
run();
}
function dispose() {
cancelThrottle === null || cancelThrottle === void 0 ? void 0 : cancelThrottle();
context._resourceTracker.release(scheduleRun, previousIdentifier);
}
onStop.then(dispose);
run = function run() {
executionCounter = executionCounter + 1;
const counter = executionCounter;
const newIdentifier = new Set(rootFieldIdentifier);
const collectResourceIdentifier = (parameter) => newIdentifier.add(this._buildResourceIdentifier(parameter));
const collectResourceIdentifier = (parameter) => newIdentifier.add(context._buildResourceIdentifier(parameter));
const addResourceIdentifier = (values) => {

@@ -316,8 +301,2 @@ if (isNone(values)) {

};
const context = {
[ORIGINAL_CONTEXT_SYMBOL]: contextValue,
collectResourceIdentifier,
addResourceIdentifier,
indices: this._indices,
};
const result = execute({

@@ -328,3 +307,7 @@ schema,

rootValue,
contextValue: context,
contextValue: {
[ORIGINAL_CONTEXT_SYMBOL]: contextValue,
collectResourceIdentifier,
addResourceIdentifier,
},
variableValues,

@@ -334,30 +317,13 @@ ...additionalArguments,

});
// result cannot be a AsyncIterableIterator if the `NoLiveMixedWithDeferStreamRule` was used.
// in case anyone forgot to add it we just panic and stop the execution :)
const handleAsyncIterator = (iterator) => {
var _a;
(_a = iterator.return) === null || _a === void 0 ? void 0 : _a.call(iterator);
record.pushValue({
errors: [
new graphql.GraphQLError(`"execute" returned a AsyncIterator instead of a MaybePromise<ExecutionResult>. The "NoLiveMixedWithDeferStreamRule" rule might have been skipped.`),
],
});
// delay to next tick to ensure the error is delivered to listeners.
// TODO: figure out whether there is a better way for doing this.
nextTick(() => {
record.iterator.return();
});
this._resourceTracker.release(record, previousIdentifier);
};
runWith(result, (result) => {
if (pushPullAsyncIterableIterator.isAsyncIterable(result)) {
handleAsyncIterator(result);
if (utils.isAsyncIterable(result)) {
onStop(new Error(`"execute" returned a AsyncIterator instead of a MaybePromise<ExecutionResult>. The "NoLiveMixedWithDeferStreamRule" rule might have been skipped.`));
return;
}
if (counter === executionCounter) {
this._resourceTracker.track(record, previousIdentifier, newIdentifier);
context._resourceTracker.track(scheduleRun, previousIdentifier, newIdentifier);
previousIdentifier = newIdentifier;
const liveResult = result;
liveResult.isLive = true;
if (this._includeIdentifierExtension === true) {
if (context._includeIdentifierExtension === true) {
if (!liveResult.extensions) {

@@ -369,25 +335,14 @@ liveResult.extensions = {};

}
record.pushValue(liveResult);
push(liveResult);
}
});
},
};
// utils for throttle
let cancelThrottle;
if (isSome(throttleValue)) {
const { run, cancel } = throttle(record.run, throttleValue);
record.run = run;
cancelThrottle = cancel;
}
this._resourceTracker.register(record, previousIdentifier);
// Execute initial query
record.run();
// TODO: figure out how we can do this stuff without monkey-patching the iterator
const originalReturn = iterator.return.bind(iterator);
iterator.return = () => {
cancelThrottle === null || cancelThrottle === void 0 ? void 0 : cancelThrottle();
this._resourceTracker.release(record, previousIdentifier);
return originalReturn();
};
return iterator;
};
if (isSome(throttleValue)) {
const throttled = throttle(run, throttleValue);
run = throttled.run;
cancelThrottle = throttled.cancel;
}
context._resourceTracker.register(scheduleRun, previousIdentifier);
scheduleRun();
});
};

@@ -408,13 +363,2 @@ /** @deprecated Please use InMemoryLiveQueryStore.makeExecute instead. */

}
if (params === null || params === void 0 ? void 0 : params.indexBy) {
this._indices = new Map();
for (const { field, args } of params.indexBy) {
let indices = this._indices.get(field);
if (!indices) {
indices = [];
this._indices.set(field, indices);
}
indices.push(args);
}
}
this._includeIdentifierExtension =

@@ -446,4 +390,4 @@ (_a = params === null || params === void 0 ? void 0 : params.includeIdentifierExtension) !== null && _a !== void 0 ? _a : (typeof process === "undefined"

const records = this._resourceTracker.getRecordsForIdentifiers(identifiers);
for (const record of records) {
record.run();
for (const run of records) {
run();
}

@@ -450,0 +394,0 @@ }

@@ -5,5 +5,2 @@ import { ExecutionResult, execute as defaultExecute, ExecutionArgs } from "graphql";

declare type PromiseOrValue<T> = T | Promise<T>;
declare type ArgumentName = string;
declare type ArgumentValue = string;
declare type IndexConfiguration = Array<ArgumentName | [arg: ArgumentName, value: ArgumentValue]>;
export declare type BuildResourceIdentifierFunction = (parameter: Readonly<{

@@ -49,9 +46,2 @@ typename: string;

validateThrottleValue?: ValidateThrottleValueFunction;
/**
* Specify which fields should be indexed for specific invalidations.
*/
indexBy?: Array<{
field: string;
args: IndexConfiguration;
}>;
};

@@ -67,3 +57,2 @@ declare type LiveExecuteReturnType = PromiseOrValue<AsyncIterableIterator<ExecutionResult | LiveExecutionResult> | ExecutionResult>;

private _validateThrottleValue;
private _indices;
constructor(params?: InMemoryLiveQueryStoreParameter);

@@ -70,0 +59,0 @@ private _getPatchedSchema;

{
"name": "@n1ru4l/in-memory-live-query-store",
"version": "0.9.0-alpha-51b566b.0",
"version": "0.9.0-alpha-e02cfcd.0",
"peerDependencies": {

@@ -10,3 +10,3 @@ "graphql": "^15.4.0 || ^16.0.0"

"@n1ru4l/graphql-live-query": "0.9.0",
"@n1ru4l/push-pull-async-iterable-iterator": "^3.0.0"
"@repeaterjs/repeater": "^3.0.4"
},

@@ -13,0 +13,0 @@ "repository": {

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc